diff --git a/packages/components/chip/index.ts b/packages/components/chip/index.ts new file mode 100644 index 00000000..2305c20f --- /dev/null +++ b/packages/components/chip/index.ts @@ -0,0 +1,8 @@ +import { withInstall } from '@puik/utils' + +import Chip from './src/chip.vue' + +export const PuikChip = withInstall(Chip) +export default PuikChip + +export * from './src/chip' diff --git a/packages/components/chip/src/chip.ts b/packages/components/chip/src/chip.ts new file mode 100644 index 00000000..79441e21 --- /dev/null +++ b/packages/components/chip/src/chip.ts @@ -0,0 +1,45 @@ +import { buildProps } from '@puik/utils' +import type { PuikTooltipPosition } from '@puik/components' +import type { ExtractPropTypes, PropType } from 'vue' +import type Chip from './chip.vue' + +export const chipSizeVariants = ['default', 'small'] as const + +export type PuikChipSizeVariant = (typeof chipSizeVariants)[number] + +export const chipProps = buildProps({ + id: { + type: String, + required: true, + default: undefined, + }, + content: { + type: String, + required: true, + default: undefined, + }, + size: { + type: String, + required: false, + default: 'default', + }, + icon: { + type: String, + default: '', + required: false, + }, + disabled: { + type: Boolean, + required: false, + default: false, + }, + tooltipPosition: { + type: String as PropType, + Required: false, + default: 'bottom', + }, +} as const) + +export type ChipProps = ExtractPropTypes + +export type ChipInstance = InstanceType diff --git a/packages/components/chip/src/chip.vue b/packages/components/chip/src/chip.vue new file mode 100644 index 00000000..af8bcfdf --- /dev/null +++ b/packages/components/chip/src/chip.vue @@ -0,0 +1,44 @@ + + + diff --git a/packages/components/chip/stories/chip.stories.ts b/packages/components/chip/stories/chip.stories.ts new file mode 100644 index 00000000..95a7ca54 --- /dev/null +++ b/packages/components/chip/stories/chip.stories.ts @@ -0,0 +1,430 @@ +import { ref } from 'vue' +import { PuikIcon, PuikButton, tooltipPositions } from '@puik/components' +import { chipSizeVariants } from '../src/chip' +import PuikChip from './../src/chip.vue' +import type { Meta, StoryFn, Args } from '@storybook/vue3' + +const chipSizeVariantsSummary = chipSizeVariants.join('|') +const tooltipPositionsSummary = tooltipPositions.join('|') + +export default { + title: 'Components/Chip', + component: PuikChip, + argTypes: { + id: { + description: + "Prop which will correspond to the component's html id attribute. NB: must not start with a number", + control: 'text', + table: { + type: { + summary: 'string', + }, + defaultValue: { + summary: 'undefined', + }, + }, + }, + content: { + description: + 'The text content (NB: if its length is equal to or greater than 30 characters it will be truncated and will be displayed entirely on hover in a tooltip)', + control: 'text', + table: { + type: { + summary: 'string', + }, + defaultValue: { + summary: 'undefined', + }, + }, + }, + size: { + description: 'Size variants of chip component (default, small)', + control: 'select', + options: chipSizeVariants, + table: { + type: { + summary: chipSizeVariantsSummary, + }, + defaultValue: { + summary: 'default', + }, + }, + }, + icon: { + description: 'Material icon name', + control: 'text', + table: { + type: { + summary: 'string', + }, + defaultValue: { + summary: 'none', + }, + }, + }, + tooltipPosition: { + description: + 'Position of the tooltip (NB: a tooltip appears if the content length is equal to or greater than 30 characters).', + control: 'select', + options: tooltipPositions, + table: { + type: { + summary: tooltipPositionsSummary, + }, + defaultValue: { + summary: 'bottom', + }, + }, + }, + disabled: { + description: 'Disables the Chip component ', + control: 'boolean', + table: { + type: { + summary: 'boolean', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + }, + args: { + id: 'puik-chip-id', + content: 'default chip', + size: 'default', + icon: '', + disabled: false, + tooltipPosition: 'bottom', + }, +} as Meta + +const DefaultTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikChip, + }, + setup() { + return { args } + }, + template: ``, +}) + +const HandleCloseEventTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikChip, + PuikButton, + }, + setup() { + const chips = ref([ + { + icon: 'home', + disabled: true, + content: "can't close disabled", + }, + { + icon: 'home', + disabled: false, + content: 'close me !', + }, + { + icon: 'home', + disabled: false, + content: 'close me !', + }, + { + icon: 'home', + disabled: false, + content: 'close me !', + }, + { + icon: 'home', + disabled: false, + content: 'close me !', + }, + { + icon: 'home', + disabled: false, + content: 'close me !', + }, + ]) + + const copyInitialChips = [...chips.value] + const handleCloseChip = (index: number) => { + chips.value.splice(index, 1) + } + const refreshChips = () => { + chips.value = [] + copyInitialChips.map((chip) => { + chips.value.push(chip) + }) + } + return { chips, args, handleCloseChip, refreshChips } + }, + template: ` +
+ +
+ + + Refresh + +`, +}) + +const SizeVariantsTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikChip, + }, + setup() { + return { args } + }, + template: ` +
+ + +
+`, +}) + +const DisabledTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikChip, + }, + setup() { + return { args } + }, + template: ` + +`, +}) + +const WithIconTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikChip, + }, + setup() { + return { args } + }, + template: ` + +`, +}) + +const WithLongTextTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikChip, + }, + setup() { + return { args } + }, + template: ` + +`, +}) + +export const Default = { + render: DefaultTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + +
+
+ default chip +
+
+`, + language: 'html', + }, + }, + }, +} + +export const HandleCloseEvent = { + render: HandleCloseEventTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + +
+ +
+ + +const handleCloseChip = (index: number) => { + // Do stuff before closing + // Then + chips.value.splice(index, 1) +} +`, + language: 'html', + }, + }, + }, +} + +export const SizeVariants = { + render: SizeVariantsTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + + + +
+
+ {$size} chip +
+
+`, + language: 'html', + }, + }, + }, +} + +export const Disabled = { + render: DisabledTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + +
+
+ disabled chip +
+
+`, + language: 'html', + }, + }, + }, +} + +export const WithIcon = { + render: WithIconTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + +
+
+ favorite +
+
with icon chip
+
+`, + language: 'html', + }, + }, + }, +} + +export const WithLongText = { + render: WithLongTextTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + +`, + language: 'html', + }, + }, + }, +} diff --git a/packages/components/chip/style/css.ts b/packages/components/chip/style/css.ts new file mode 100644 index 00000000..e76edcb3 --- /dev/null +++ b/packages/components/chip/style/css.ts @@ -0,0 +1,2 @@ +import '@puik/components/base/style/css' +import '@puik/theme/puik-chip.css' diff --git a/packages/components/chip/style/index.ts b/packages/components/chip/style/index.ts new file mode 100644 index 00000000..1e392966 --- /dev/null +++ b/packages/components/chip/style/index.ts @@ -0,0 +1,2 @@ +import '@puik/components/base/style' +import '@puik/theme/src/chip.scss' diff --git a/packages/components/chip/test/chip.spec.ts b/packages/components/chip/test/chip.spec.ts new file mode 100644 index 00000000..41c2a904 --- /dev/null +++ b/packages/components/chip/test/chip.spec.ts @@ -0,0 +1,54 @@ +import { mount } from '@vue/test-utils' +import { describe, it, expect } from 'vitest' +import PuikChip from '../src/chip.vue' +import type { MountingOptions, VueWrapper } from '@vue/test-utils' + +describe('Chip tests', () => { + let wrapper: VueWrapper + const findChip = () => wrapper.find('.puik-chip') + const findChipContent = () => wrapper.find('.puik-chip__content') + const findCloseBtn = () => wrapper.find('.puik-chip__close') + const findLeftIcon = () => wrapper.find('.puik-chip__icon') + + const factory = ( + propsData: Record = {}, + options: MountingOptions = {} + ) => { + wrapper = mount(PuikChip, { + props: { + ...propsData, + }, + ...options, + }) + } + + it('should be a vue instance', () => { + factory() + expect(wrapper).toBeTruthy() + }) + + it('as id prop value is "puik-chip-example", id html attribute of puik-chip should be "puik-chip-example"', () => { + factory({ id: 'puik-chip-example' }) + expect(findChip().attributes().id).toBe('puik-chip-example') + }) + + it('Chip text should be "content"', () => { + factory({ content: 'content' }) + expect(findChipContent().text()).toBe('content') + }) + + it('should display a chip small version', () => { + factory({ size: 'small' }) + expect(findChip().classes()).toContain('puik-chip--small') + }) + + it('should display a chip version with left icon', () => { + factory({ icon: 'home' }) + expect(findLeftIcon().text()).toBe('home') + }) + + it('should display a chip disabled version', () => { + factory({ disabled: true }) + expect(findChip().classes()).toContain('puik-chip--disabled') + }) +}) diff --git a/packages/components/index.ts b/packages/components/index.ts index bc6d7e31..d0a24516 100644 --- a/packages/components/index.ts +++ b/packages/components/index.ts @@ -27,3 +27,5 @@ export * from './sidebar' export * from './textarea' export * from './tab-navigation' export * from './progress-stepper' +export * from './chip' +export * from './tag' diff --git a/packages/components/snackbar/src/snackbar.ts b/packages/components/snackbar/src/snackbar.ts index caef015a..46e51e64 100644 --- a/packages/components/snackbar/src/snackbar.ts +++ b/packages/components/snackbar/src/snackbar.ts @@ -2,7 +2,7 @@ import { buildProps } from '@puik/utils' import type { ExtractPropTypes, PropType } from 'vue' import type Snackbar from './snackbar.vue' -export const snackbarVariants = ['default', 'danger'] as const +export const snackbarVariants = ['default', 'danger', 'success'] as const export type PuikSnackbarVariant = (typeof snackbarVariants)[number] export interface SnackbarAction { diff --git a/packages/components/snackbar/stories/snackbar.stories.ts b/packages/components/snackbar/stories/snackbar.stories.ts index b46ccf49..ad7967cf 100644 --- a/packages/components/snackbar/stories/snackbar.stories.ts +++ b/packages/components/snackbar/stories/snackbar.stories.ts @@ -119,12 +119,18 @@ const WithoutActionTemplate: StoryFn = () => ({ text: 'Unable to update settings.', variant: 'danger', }) - return { displaySnackbar, displayErrorSnackbar } + const displaySuccessSnackbar = () => + PuikSnackbar({ + text: 'Settings updated successfully.', + variant: 'success', + }) + return { displaySnackbar, displayErrorSnackbar, displaySuccessSnackbar } }, template: `
Display Snackbar Display Error Snackbar + Display Success Snackbar
`, }) @@ -139,6 +145,7 @@ export const WithoutAction: StoryObj = { @@ -179,6 +191,13 @@ const displayErrorSnackbar = () => close + +
+ Settings updated successfully. + +
`, language: 'html', }, @@ -208,12 +227,22 @@ const WithActionTemplate: StoryFn = () => ({ callback: action('Error snackbar action callback function'), }, }) - return { displaySnackbar, displayErrorSnackbar } + const displaySuccessSnackbar = () => + PuikSnackbar({ + text: 'Settings updated successfully.', + variant: 'success', + action: { + label: 'Cancel', + callback: action('Success snackbar action callback function'), + }, + }) + return { displaySnackbar, displayErrorSnackbar, displaySuccessSnackbar } }, template: `
Display Snackbar Display Error Snackbar + Display Success Snackbar
`, }) @@ -228,6 +257,7 @@ export const WithAction: StoryObj = { @@ -278,6 +317,14 @@ export const WithAction: StoryObj = { close + +
+ Settings updated successfully. + + +
`, language: 'html', }, diff --git a/packages/components/snackbar/test/snackbar.spec.ts b/packages/components/snackbar/test/snackbar.spec.ts index e851b600..afa5abf5 100644 --- a/packages/components/snackbar/test/snackbar.spec.ts +++ b/packages/components/snackbar/test/snackbar.spec.ts @@ -66,6 +66,14 @@ describe('Snackbar tests', () => { expect(findAction().exists()).toBeFalsy() }) + it('should be a success snackbar without action', () => { + const text = faker.lorem.sentence() + factory({ text, variant: 'success' }) + expect(findText().text()).toEqual(text) + expect(findSnackbar().classes()).toContain('puik-snackbar--success') + expect(findAction().exists()).toBeFalsy() + }) + it('should be a dangerous snackbar with action', async () => { const text = faker.lorem.sentence() const label = faker.lorem.word() @@ -86,6 +94,26 @@ describe('Snackbar tests', () => { expect(callback).toBeCalled() }) + it('should be a success snackbar with action', async () => { + const text = faker.lorem.sentence() + const label = faker.lorem.word() + const callback = vi.fn() + factory({ + text, + action: { + label, + callback, + }, + variant: 'success', + }) + expect(findAction().exists()).toBeTruthy() + expect(findText().text()).toEqual(text) + expect(findSnackbar().classes()).toContain('puik-snackbar--success') + expect(findAction().text()).toEqual(label) + await findAction().trigger('click') + expect(callback).toBeCalled() + }) + it('should close the snackbar when clicking on the close button', async () => { const text = faker.lorem.sentence() await factory({ text }) diff --git a/packages/components/tag/index.ts b/packages/components/tag/index.ts new file mode 100644 index 00000000..69156075 --- /dev/null +++ b/packages/components/tag/index.ts @@ -0,0 +1,8 @@ +import { withInstall } from '@puik/utils' + +import Tag from './src/tag.vue' + +export const PuikTag = withInstall(Tag) +export default PuikTag + +export * from './src/tag' diff --git a/packages/components/tag/src/tag.ts b/packages/components/tag/src/tag.ts new file mode 100644 index 00000000..f0b1ec83 --- /dev/null +++ b/packages/components/tag/src/tag.ts @@ -0,0 +1,59 @@ +import { buildProps } from '@puik/utils' +import type { PuikTooltipPosition } from '@puik/components' +import type { ExtractPropTypes, PropType } from 'vue' +import type Tag from './tag.vue' + +export const tagColorsVariants = [ + 'neutral', + 'blue', + 'yellow', + 'green', + 'purple', +] as const + +export const tagSizeVariants = ['default', 'small'] as const + +export type PuikTagColorVariant = (typeof tagColorsVariants)[number] +export type PuikTagSizeVariant = (typeof tagSizeVariants)[number] + +export const tagProps = buildProps({ + id: { + type: String, + required: true, + default: undefined, + }, + content: { + type: String, + required: true, + default: undefined, + }, + variant: { + type: String, + required: false, + default: 'neutral', + }, + size: { + type: String, + required: false, + default: 'default', + }, + icon: { + type: String, + default: '', + required: false, + }, + disabled: { + type: Boolean, + required: false, + default: false, + }, + tooltipPosition: { + type: String as PropType, + Required: false, + default: 'bottom', + }, +} as const) + +export type TagProps = ExtractPropTypes + +export type TagInstance = InstanceType diff --git a/packages/components/tag/src/tag.vue b/packages/components/tag/src/tag.vue new file mode 100644 index 00000000..21f7bc8e --- /dev/null +++ b/packages/components/tag/src/tag.vue @@ -0,0 +1,43 @@ + + + diff --git a/packages/components/tag/stories/tag.stories.ts b/packages/components/tag/stories/tag.stories.ts new file mode 100644 index 00000000..cc3d6251 --- /dev/null +++ b/packages/components/tag/stories/tag.stories.ts @@ -0,0 +1,416 @@ +import { ref } from 'vue' +import { PuikIcon, tooltipPositions } from '@puik/components' +import { tagColorsVariants, tagSizeVariants } from '../src/tag' +import PuikTag from './../src/tag.vue' +import type { Meta, StoryFn, Args } from '@storybook/vue3' + +const tagColorsVariantsSummary = tagColorsVariants.join('|') +const tagSizeVariantsSummary = tagSizeVariants.join('|') +const tooltipPositionsSummary = tooltipPositions.join('|') + +export default { + title: 'Components/Tag', + component: PuikTag, + argTypes: { + id: { + description: + "Prop which will correspond to the component's html id attribute. NB: must not start with a number", + control: 'text', + table: { + type: { + summary: 'string', + }, + defaultValue: { + summary: 'undefined', + }, + }, + }, + content: { + description: + 'The text content (NB: if its length is equal to or greater than 30 characters it will be truncated and will be displayed entirely on hover in a tooltip)', + control: 'text', + table: { + type: { + summary: 'string', + }, + defaultValue: { + summary: 'undefined', + }, + }, + }, + size: { + description: 'Size variants of tag component (default, small)', + control: 'select', + options: tagSizeVariants, + table: { + type: { + summary: tagSizeVariantsSummary, + }, + defaultValue: { + summary: 'default', + }, + }, + }, + variant: { + description: + 'Color variants of tag component (neutral by default, blue, yellow, green, purple)', + control: 'select', + options: tagColorsVariants, + table: { + type: { + summary: tagColorsVariantsSummary, + }, + defaultValue: { + summary: 'neutral', + }, + }, + }, + icon: { + description: 'Material icon name', + control: 'text', + table: { + type: { + summary: 'string', + }, + defaultValue: { + summary: 'none', + }, + }, + }, + tooltipPosition: { + description: + 'Position of the tooltip (NB: a tooltip appears if the content length is equal to or greater than 30 characters).', + control: 'select', + options: tooltipPositions, + table: { + type: { + summary: tooltipPositionsSummary, + }, + defaultValue: { + summary: 'bottom', + }, + }, + }, + disabled: { + description: 'Disables the Tag component ', + control: 'boolean', + table: { + type: { + summary: 'boolean', + }, + defaultValue: { + summary: 'false', + }, + }, + }, + }, + args: { + id: 'puik-tag-id', + content: 'default tag', + size: 'default', + variant: 'neutral', + icon: '', + disabled: false, + tooltipPosition: 'bottom', + }, +} as Meta + +const DefaultTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikTag, + }, + setup() { + return { args } + }, + template: ``, +}) + +const ColorVariantsTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikTag, + }, + setup() { + const tags = ref([ + { + variant: 'neutral', + content: 'neutral tag', + }, + { + variant: 'blue', + content: 'blue tag', + }, + { + variant: 'yellow', + content: 'yellow tag', + }, + { + variant: 'green', + content: 'green tag', + }, + { + variant: 'purple', + content: 'purple tag', + }, + ]) + + return { tags, args } + }, + template: ` +
+ +
+`, +}) + +const SizeVariantsTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikTag, + }, + setup() { + return { args } + }, + template: ` + + +`, +}) + +const DisabledTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikTag, + }, + setup() { + return { args } + }, + template: ` + +`, +}) + +const WithIconTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikTag, + }, + setup() { + return { args } + }, + template: ` + +`, +}) + +const WithLongTextTemplate: StoryFn = (args: Args) => ({ + components: { + PuikIcon, + PuikTag, + }, + setup() { + return { args } + }, + template: ` + +`, +}) + +export const Default = { + render: DefaultTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + +
+
+ default tag +
+
+`, + language: 'html', + }, + }, + }, +} + +export const ColorVariants = { + render: ColorVariantsTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + + + +
+
+ {$variant} tag +
+
+`, + language: 'html', + }, + }, + }, +} + +export const SizeVariants = { + render: SizeVariantsTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + + + +
+
+ {$size} tag +
+
+`, + language: 'html', + }, + }, + }, +} + +export const Disabled = { + render: DisabledTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + +
+
+ disabled tag +
+
+`, + language: 'html', + }, + }, + }, +} + +export const WithIcon = { + render: WithIconTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + + + +
+
+ favorite +
+
with icon tag
+
+`, + language: 'html', + }, + }, + }, +} + +export const WithLongText = { + render: WithLongTextTemplate, + args: {}, + parameters: { + docs: { + source: { + code: ` + + + +`, + language: 'html', + }, + }, + }, +} diff --git a/packages/components/tag/style/css.ts b/packages/components/tag/style/css.ts new file mode 100644 index 00000000..766ee1bf --- /dev/null +++ b/packages/components/tag/style/css.ts @@ -0,0 +1,2 @@ +import '@puik/components/base/style/css' +import '@puik/theme/puik-tag.css' diff --git a/packages/components/tag/style/index.ts b/packages/components/tag/style/index.ts new file mode 100644 index 00000000..7666132b --- /dev/null +++ b/packages/components/tag/style/index.ts @@ -0,0 +1,2 @@ +import '@puik/components/base/style' +import '@puik/theme/src/tag.scss' diff --git a/packages/components/tag/test/tag.spec.ts b/packages/components/tag/test/tag.spec.ts new file mode 100644 index 00000000..bd3bd926 --- /dev/null +++ b/packages/components/tag/test/tag.spec.ts @@ -0,0 +1,58 @@ +import { mount } from '@vue/test-utils' +import { describe, it, expect } from 'vitest' +import PuikTag from '../src/tag.vue' +import type { MountingOptions, VueWrapper } from '@vue/test-utils' + +describe('Tag tests', () => { + let wrapper: VueWrapper + const findTag = () => wrapper.find('.puik-tag') + const findTagContent = () => wrapper.find('.puik-tag__content') + const findLeftIcon = () => wrapper.find('.puik-tag__icon') + + const factory = ( + propsData: Record = {}, + options: MountingOptions = {} + ) => { + wrapper = mount(PuikTag, { + props: { + ...propsData, + }, + ...options, + }) + } + + it('should be a vue instance', () => { + factory() + expect(wrapper).toBeTruthy() + }) + + it('as id prop value is "puik-tag-example", id html attribute of puik-tag should be "puik-tag-example"', () => { + factory({ id: 'puik-tag-example' }) + expect(findTag().attributes().id).toBe('puik-tag-example') + }) + + it('Tag text should be "content"', () => { + factory({ content: 'content' }) + expect(findTagContent().text()).toBe('content') + }) + + it('should display a blue version of the tag', () => { + factory({ variant: 'blue' }) + expect(findTag().classes()).toContain('puik-tag--blue') + }) + + it('should display a tag small version', () => { + factory({ size: 'small' }) + expect(findTag().classes()).toContain('puik-tag--small') + }) + + it('should display a tag version with left icon', () => { + factory({ icon: 'home' }) + expect(findLeftIcon().text()).toBe('home') + }) + + it('should display a tag disabled version', () => { + factory({ disabled: true }) + expect(findTag().classes()).toContain('puik-tag--disabled') + }) +}) diff --git a/packages/components/tooltip/src/tooltip.ts b/packages/components/tooltip/src/tooltip.ts index ab24ac2e..ec2a5c35 100644 --- a/packages/components/tooltip/src/tooltip.ts +++ b/packages/components/tooltip/src/tooltip.ts @@ -18,7 +18,7 @@ export const tooltipProps = buildProps({ position: { type: String as PropType, required: false, - default: 'top', + default: 'bottom', }, isDisabled: { type: Boolean, diff --git a/packages/puik/component.ts b/packages/puik/component.ts index bc64f9b7..ee5533d9 100644 --- a/packages/puik/component.ts +++ b/packages/puik/component.ts @@ -1,3 +1,5 @@ +import { PuikTag } from '@puik/components/tag' +import { PuikChip } from '@puik/components/chip' import { PuikTabNavigation, PuikTabNavigationGroupPanels, @@ -48,6 +50,8 @@ import type { Plugin } from 'vue' // prettier-ignore export default [ + PuikTag, + PuikChip, PuikTabNavigationGroupPanels, PuikTabNavigationTitle, PuikTabNavigationGroupTitles, diff --git a/packages/theme/src/chip.scss b/packages/theme/src/chip.scss new file mode 100644 index 00000000..df4288c5 --- /dev/null +++ b/packages/theme/src/chip.scss @@ -0,0 +1,37 @@ +@use './common/typography.scss'; + +.puik-chip { + @extend .puik-body-small; + @apply bg-primary-300 text-primary max-w-fit font-bold flex items-center; + + &--default { + @apply px-2 py-[3px]; + } + &--small { + @apply px-1 py-0; + .puik-chip__close { + @apply p-[1px]; + } + } + &--disabled { + @apply bg-primary-200 text-primary-500; + .puik-chip__close { + @apply cursor-not-allowed hover:bg-primary-200; + } + } + &__close { + @apply p-[3px] ml-auto cursor-pointer rounded-[50%] hover:bg-primary-400; + } + &__icon { + @apply mr-1; + } + &__content { + @apply max-w-[150px] pr-[2px] overflow-hidden whitespace-nowrap text-ellipsis; + & > .puik-tooltip { + @apply max-w-[150px] overflow-hidden whitespace-nowrap text-ellipsis; + } + } + &__content .puik-tooltip__wrapper { + @apply max-w-[150px] mr-1 pr-[2px] overflow-hidden whitespace-nowrap text-ellipsis; + } +} diff --git a/packages/theme/src/index.scss b/packages/theme/src/index.scss index 14e753de..d888a495 100644 --- a/packages/theme/src/index.scss +++ b/packages/theme/src/index.scss @@ -40,3 +40,5 @@ @use 'tab-navigation-group-panels'; @use 'progress-stepper'; @use 'progress-stepper-step'; +@use 'chip'; +@use 'tag'; diff --git a/packages/theme/src/snackbar.scss b/packages/theme/src/snackbar.scss index 6d4010ba..6fcccda0 100644 --- a/packages/theme/src/snackbar.scss +++ b/packages/theme/src/snackbar.scss @@ -9,6 +9,10 @@ @apply bg-red-500; } + &--success { + @apply bg-green-500; + } + &__text { @apply font-primary flex-grow; } diff --git a/packages/theme/src/tag.scss b/packages/theme/src/tag.scss new file mode 100644 index 00000000..f5d8a57a --- /dev/null +++ b/packages/theme/src/tag.scss @@ -0,0 +1,52 @@ +@use './common/typography.scss'; + +.puik-tag { + @extend .puik-body-small; + @apply max-w-fit font-bold flex items-center; + + &--default { + @apply px-2 py-[3px]; + } + &--small { + @apply px-1 py-0; + .puik-tag__close { + @apply p-[1px]; + } + } + &--neutral { + @apply bg-primary-300 text-primary; + } + &--blue { + @apply bg-ocean-blue-50 text-primary; + } + &--yellow { + @apply bg-amber-100 text-primary; + } + &--green { + @apply bg-green-50 text-primary; + } + &--purple { + @apply bg-purple-50 text-primary; + } + &--disabled { + @apply bg-primary-200 text-primary-500; + .puik-tag__close { + @apply cursor-not-allowed hover:bg-primary-200; + } + } + &__close { + @apply p-[3px] ml-auto cursor-pointer rounded-[50%] hover:bg-primary-400; + } + &__icon { + @apply mr-1; + } + &__content { + @apply max-w-[150px] pr-[2px] overflow-hidden whitespace-nowrap text-ellipsis; + & > .puik-tooltip { + @apply max-w-[150px] overflow-hidden whitespace-nowrap text-ellipsis; + } + } + &__content .puik-tooltip__wrapper { + @apply max-w-[150px] mr-1 pr-[2px] overflow-hidden whitespace-nowrap text-ellipsis; + } +} diff --git a/typings/global.d.ts b/typings/global.d.ts index 7252421a..df474081 100644 --- a/typings/global.d.ts +++ b/typings/global.d.ts @@ -1,6 +1,7 @@ // GlobalComponents for Volar declare module '@vue/runtime-core' { export interface GlobalComponents { + PuikTag: typeof import('@prestashopcorp/puik')['PuikTag'] PuikTabNavigationGroupPanels: typeof import('@prestashopcorp/puik')['PuikTabNavigationGroupPanels'] PuikTabNavigationTitle: typeof import('@prestashopcorp/puik')['PuikTabNavigationTitle'] PuikTabNavigationGroupTitles: typeof import('@prestashopcorp/puik')['PuikTabNavigationGroupTitles']