diff --git a/packages/components/alert/src/alert.ts b/packages/components/alert/src/alert.ts index f179699e..abe388d4 100644 --- a/packages/components/alert/src/alert.ts +++ b/packages/components/alert/src/alert.ts @@ -37,6 +37,11 @@ export const alertProps = buildProps({ required: false, default: undefined, }, + buttonWrapLabel: { + type: Boolean, + required: false, + default: false, + }, isClosable: { type: Boolean, required: false, diff --git a/packages/components/alert/src/alert.vue b/packages/components/alert/src/alert.vue index b557d50f..49c93bb4 100644 --- a/packages/components/alert/src/alert.vue +++ b/packages/components/alert/src/alert.vue @@ -32,6 +32,7 @@ ({ + components: { + PuikAlert, + }, + template: ` +
+ + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + + + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + +
+ `, + }), + + parameters: { + docs: { + source: { + code: ` + + + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + + + + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + This an alert with a very long description. + + + +
+
+
check_circle
+
+

buttonWrapLabel to true

+ This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. +
+
+ +
+ +
+
+
check_circle
+
+

buttonWrapLabel to false (by default)

+ This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. This an alert with a very long description. +
+
+ +
+ `, + language: 'html', + }, + }, + }, +} + export const Success: StoryObj = { render: () => ({ components: { diff --git a/packages/components/alert/test/alert.spec.ts b/packages/components/alert/test/alert.spec.ts index f670a7ea..baeaf11b 100644 --- a/packages/components/alert/test/alert.spec.ts +++ b/packages/components/alert/test/alert.spec.ts @@ -40,6 +40,11 @@ describe('Alert tests', () => { expect(findAlert().classes()).toContain('puik-alert--warning') }) + it('should set the button label wrap to false', () => { + factory({ buttonLabel: 'Button', buttonWrapLabel: false }) + expect(findButton().classes()).toContain('puik-button--no-wrap') + }) + it('should display a button which emits the click event on click', () => { factory({ buttonLabel: 'Button' }) expect(findButton().exists()).toBeTruthy() diff --git a/packages/components/button/src/button.ts b/packages/components/button/src/button.ts index a6885676..f0158d3f 100644 --- a/packages/components/button/src/button.ts +++ b/packages/components/button/src/button.ts @@ -38,6 +38,11 @@ export const buttonProps = buildProps({ required: false, default: false, }, + wrapLabel: { + type: Boolean, + required: false, + default: false, + }, disabled: { type: Boolean, required: false, diff --git a/packages/components/button/src/button.vue b/packages/components/button/src/button.vue index 5c095584..4f667329 100644 --- a/packages/components/button/src/button.vue +++ b/packages/components/button/src/button.vue @@ -8,6 +8,7 @@ `puik-button--${size}`, { 'puik-button--disabled': disabled }, { 'puik-button--fluid': fluid }, + { 'puik-button--no-wrap': !wrapLabel }, ]" :disabled="disabled" :data-test="dataTest" diff --git a/packages/components/button/stories/button.stories.ts b/packages/components/button/stories/button.stories.ts index a71e84a2..728cbcdb 100644 --- a/packages/components/button/stories/button.stories.ts +++ b/packages/components/button/stories/button.stories.ts @@ -44,6 +44,14 @@ export default { }, }, }, + wrapLabel: { + description: 'Set the carriage return of the button label', + table: { + defaultValue: { + summary: false, + }, + }, + }, disabled: { description: 'Set the button as disabled', table: { @@ -81,6 +89,7 @@ export default { variant: 'primary', size: 'md', fluid: false, + wrapLabel: true, disabled: false, leftIcon: '', rightIcon: '', @@ -117,6 +126,7 @@ export const Default = { :size="$sizes" :variant="$variants" :fluid="true|false" + :wrap-label="true|false" :disabled="true|false" :left-icon="leftIcon" :right-icon="rightIcon" diff --git a/packages/components/button/test/button.spec.ts b/packages/components/button/test/button.spec.ts index a209f85c..da319d3e 100644 --- a/packages/components/button/test/button.spec.ts +++ b/packages/components/button/test/button.spec.ts @@ -91,6 +91,11 @@ describe('Button tests', () => { expect(findButton().classes()).toContain('puik-button--fluid') }) + it('should set the button label wrap to false', () => { + factory({ wrapLabel: false }) + expect(findButton().classes()).toContain('puik-button--no-wrap') + }) + it('should be a router-link if to prop is defined', () => { factory({ to: '/test' }) expect(findButton().element.tagName).toBe('ROUTER-LINK') diff --git a/packages/components/table/src/table.ts b/packages/components/table/src/table.ts index 61cce8f3..12274792 100644 --- a/packages/components/table/src/table.ts +++ b/packages/components/table/src/table.ts @@ -20,6 +20,11 @@ export const tableProps = buildProps({ required: false, default: () => [], }, + expandable: { + type: Boolean, + required: false, + default: false, + }, selectable: { type: Boolean, required: false, @@ -35,6 +40,16 @@ export const tableProps = buildProps({ required: false, default: false, }, + stickyFirstCol: { + type: Boolean, + required: false, + default: false, + }, + stickyLastCol: { + type: Boolean, + required: false, + default: false, + }, } as const) export type TableProps = ExtractPropTypes diff --git a/packages/components/table/src/table.vue b/packages/components/table/src/table.vue index 7e7af7cf..396bf713 100644 --- a/packages/components/table/src/table.vue +++ b/packages/components/table/src/table.vue @@ -1,13 +1,25 @@ @@ -79,6 +170,7 @@ import { computed, ref, watch } from 'vue' import { useLocale } from '@puik/hooks' import PuikCheckbox from '../../checkbox/src/checkbox.vue' +import PuikIcon from '../../icon/src/icon.vue' import { tableProps } from './table' defineOptions({ name: 'PuikTable', @@ -92,6 +184,48 @@ const emit = defineEmits<{ }>() const { t } = useLocale() const checked = ref(props.selection) +const expandedRows = ref([]) +const ScrollBarPosition = ref('left') +let lastScrollLeft = 0 + +const getScrollBarPosition = async (event: Event) => { + const target = event.target as HTMLElement + if (target.scrollLeft === 0) { + ScrollBarPosition.value = 'left' + } else if ( + Math.abs(target.scrollLeft + target.offsetWidth - target.scrollWidth) < 10 + ) { + ScrollBarPosition.value = 'right' + } else { + ScrollBarPosition.value = 'isScrolling' + } + + lastScrollLeft = target.scrollLeft +} + +const isSticky = ( + index: number, + selectable: boolean = props.selectable, + expandable: boolean = props.expandable +): boolean => { + if (selectable || expandable) { + return props.stickyLastCol && index === props.headers.length - 1 + } else { + return ( + (props.stickyFirstCol && index === 0) || + (props.stickyLastCol && index === props.headers.length - 1) + ) + } +} + +const expandRow = (rowIndex: number) => { + const position = expandedRows.value.indexOf(rowIndex) + if (position !== -1) { + expandedRows.value.splice(position, 1) + } else { + expandedRows.value.push(rowIndex) + } +} const selectAll = computed(() => { if (indeterminate.value) return false diff --git a/packages/components/table/stories/table.stories.ts b/packages/components/table/stories/table.stories.ts index 3be1d3f0..9052f774 100644 --- a/packages/components/table/stories/table.stories.ts +++ b/packages/components/table/stories/table.stories.ts @@ -58,7 +58,15 @@ export default { }, selectable: { control: 'boolean', - description: 'Add col with checkbox', + description: 'Makes rows selectable', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: 'false' }, + }, + }, + expandable: { + control: 'boolean', + description: 'Makes rows expandable', table: { type: { summary: 'boolean' }, defaultValue: { summary: 'false' }, @@ -88,6 +96,22 @@ export default { }, }, }, + stickyFirstCol: { + control: 'boolean', + description: 'Makes the first column sticky', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: 'false' }, + }, + }, + stickyLastCol: { + control: 'boolean', + description: 'Makes the last column sticky', + table: { + type: { summary: 'boolean' }, + defaultValue: { summary: 'false' }, + }, + }, '`header-${header.value}`': { control: 'none', description: 'Slot to replace header', @@ -113,6 +137,21 @@ export default { { item: any index: number +} + `, + }, + }, + }, + '`expanded-row-${rowIndex}`': { + control: 'none', + description: 'slot for expanded row content', + table: { + type: { + summary: 'SlotProps', + detail: ` +{ + item: any + index: number } `, }, @@ -143,7 +182,10 @@ export default { }, args: { selectable: false, + expandable: false, fullWidth: false, + stickyFirstCol: false, + stickyLastCol: false, }, } as Meta @@ -415,6 +457,7 @@ export const Selectable: StoryObj = { v-model:selection="selection" :headers="headers" :items="items" + :selectable="true" >