diff --git a/docs/reference/config.md b/docs/reference/config.md index 6dc3fe41..c71b9e00 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -252,6 +252,7 @@ Each object in the array is a preset with the following properties: - `label: string`: Label for the preset. - `color: string`: Color of the preset. +- `contrastColor?: string`: Contrast color of preset Default values are shown in the example below: @@ -261,27 +262,40 @@ export default defineConfig({ { label: 'Transparent', color: 'transparent', + contrastColor: '#333' }, { label: 'White', color: '#fff', + contrastColor: '#333' }, { label: 'Light gray', color: '#aaa', + contrastColor: '#eee' }, { label: 'Dark gray', color: '#333', + contrastColor: '#ccc' }, { label: 'Black', color: '#000', + contrastColor: '#fff' }, ], }) ``` +You can use current contrast color via the css variable `--histoire-contrast-color`: + +```css +.my-class { + color: var(--histoire-contrast-color); +} +``` + ## `sandboxDarkClass` `string` - Default: `'dark'` diff --git a/examples/vue3/cypress/integration/stories-list.js b/examples/vue3/cypress/integration/stories-list.js index b79aa44d..a6acb601 100644 --- a/examples/vue3/cypress/integration/stories-list.js +++ b/examples/vue3/cypress/integration/stories-list.js @@ -4,7 +4,7 @@ describe('Stories list', () => { it('should display the stories', () => { cy.clearLocalStorage() cy.visit('/') - cy.get('[data-test-id="story-list-item"]').should('have.length', 26) + cy.get('[data-test-id="story-list-item"]').should('have.length', 27) cy.get('[data-test-id="story-list-item"]').contains('🐱 Meow') cy.get('[data-test-id="story-list-item"]').contains('BaseButton') .contains('3') // Variants count diff --git a/examples/vue3/cypress/integration/toolbar-background.js b/examples/vue3/cypress/integration/toolbar-background.js new file mode 100644 index 00000000..ad3ff05f --- /dev/null +++ b/examples/vue3/cypress/integration/toolbar-background.js @@ -0,0 +1,57 @@ +/// + +describe('background color', () => { + const getIframeBody = () => cy.get('iframe[data-test-id="preview-iframe"]') + .its('0.contentDocument.body').should('not.be.empty') + .then(cy.wrap) + + const backgroundColorShouldBe = [ + 'rgba(0, 0, 0, 0)', + 'rgb(255, 255, 255)', + 'rgb(170, 170, 170)', + 'rgb(51, 51, 51)', + 'rgb(0, 0, 0)', + 'rgb(202, 255, 245)', + ] + + const contrastColorShouldBe = [ + 'rgb(51, 51, 51)', + 'rgb(51, 51, 51)', + 'rgb(0, 0, 0)', + 'rgb(255, 255, 255)', + 'rgb(238, 238, 238)', + 'rgb(0, 81, 66)', + ] + + it('should provide background and contrast color (no iframe)', () => { + cy.visit('/story/src-components-complexparameter-story-vue?variantId=_default') + cy.get('[data-test-id="toolbar-background"]').click() + cy.get('[data-test-id="background-popper"]').should('be.visible').find('button').should('have.length', 6).each(($el, index) => { + cy.wrap($el).click() + cy.get('[data-test-id="responsive-preview-bg"]').should('have.css', 'background-color', backgroundColorShouldBe[index]) + cy.get('[data-test-id="story-variant-single-view"] .native-story').should('have.css', 'color', contrastColorShouldBe[index]) + cy.get('[data-test-id="toolbar-background"]').click() + }) + }) + + it('should provide background and contrast color (with iframe)', () => { + cy.visit('story/src-components-contrastcolor-story-vue?variantId=_default') + cy.get('[data-test-id="toolbar-background"]').click() + cy.get('[data-test-id="background-popper"]').should('be.visible').find('button').should('have.length', 6).each(($el, index) => { + cy.wrap($el).click() + getIframeBody().find('.contrast-color').should('have.css', 'color', contrastColorShouldBe[index]) + cy.get('[data-test-id="toolbar-background"]').click() + }) + }) + + it('should provide background and contrast color (grid)', () => { + cy.visit('/story/src-components-substory-story-vue?variantId=src-components-substory-story-vue-0') + cy.get('[data-test-id="toolbar-background"]').click() + cy.get('[data-test-id="background-popper"]').should('be.visible').find('button').should('have.length', 6).each(($el, index) => { + cy.wrap($el).click() + cy.get('[data-test-id="responsive-preview-bg"]').should('have.css', 'background-color', backgroundColorShouldBe[index]) + cy.get('.__histoire-sandbox .text').should('have.css', 'color', contrastColorShouldBe[index]) + cy.get('[data-test-id="toolbar-background"]').click() + }) + }) +}) diff --git a/examples/vue3/histoire.config.ts b/examples/vue3/histoire.config.ts index a9fed307..a24d6981 100644 --- a/examples/vue3/histoire.config.ts +++ b/examples/vue3/histoire.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from 'histoire' +import { defineConfig, getDefaultConfig } from 'histoire' import { HstVue } from '@histoire/plugin-vue' export default defineConfig({ @@ -6,4 +6,12 @@ export default defineConfig({ plugins: [ HstVue(), ], + backgroundPresets: [ + ...(getDefaultConfig().backgroundPresets || []), + { + label: 'Custom gray', + color: '#cafff5', + contrastColor: '#005142', + }, + ], }) diff --git a/examples/vue3/src/components/ComplexParameter.vue b/examples/vue3/src/components/ComplexParameter.vue index e261054b..85ebee1d 100644 --- a/examples/vue3/src/components/ComplexParameter.vue +++ b/examples/vue3/src/components/ComplexParameter.vue @@ -18,3 +18,9 @@ const props = defineProps<{ {{ recursiveParameter.name }} + + diff --git a/examples/vue3/src/components/ContrastColor.story.vue b/examples/vue3/src/components/ContrastColor.story.vue new file mode 100644 index 00000000..2326eb84 --- /dev/null +++ b/examples/vue3/src/components/ContrastColor.story.vue @@ -0,0 +1,11 @@ + + + diff --git a/examples/vue3/src/components/SubStory.story.vue b/examples/vue3/src/components/SubStory.story.vue index f477f8f6..96c36322 100644 --- a/examples/vue3/src/components/SubStory.story.vue +++ b/examples/vue3/src/components/SubStory.story.vue @@ -7,7 +7,15 @@ }" > -

This is a sub story

+

+ This is a sub story +

+ + diff --git a/packages/histoire-app/src/app/components/story/StoryResponsivePreview.vue b/packages/histoire-app/src/app/components/story/StoryResponsivePreview.vue index 53b8dff9..5c2f1398 100644 --- a/packages/histoire-app/src/app/components/story/StoryResponsivePreview.vue +++ b/packages/histoire-app/src/app/components/story/StoryResponsivePreview.vue @@ -139,7 +139,10 @@ const isResponsiveEnabled = computed(() => !props.variant.responsiveDisabled) 'htw-h-fit': !!finalHeight } : undefined" > -
+
-
+
-
+
diff --git a/packages/histoire-app/src/app/components/toolbar/ToolbarBackground.vue b/packages/histoire-app/src/app/components/toolbar/ToolbarBackground.vue index add0bab3..5f0d7f7c 100644 --- a/packages/histoire-app/src/app/components/toolbar/ToolbarBackground.vue +++ b/packages/histoire-app/src/app/components/toolbar/ToolbarBackground.vue @@ -1,10 +1,14 @@