@liftkit-vue/core 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +11 -7
  3. package/src/components/LkBadge.vue +64 -0
  4. package/src/components/LkButton.vue +102 -0
  5. package/src/components/LkCard.vue +85 -0
  6. package/src/components/LkColumn.vue +40 -0
  7. package/src/components/LkContainer.vue +26 -0
  8. package/src/components/LkDropdown/LkDropdown.vue +14 -0
  9. package/src/components/LkDropdown/LkDropdownMenu.vue +99 -0
  10. package/src/components/LkDropdown/LkDropdownTrigger.vue +39 -0
  11. package/src/components/LkDropdown/index.ts +3 -0
  12. package/src/components/LkGrid.vue +58 -0
  13. package/src/components/LkHeading.vue +43 -0
  14. package/src/components/LkIcon.vue +56 -0
  15. package/src/components/LkIconButton.vue +78 -0
  16. package/src/components/LkImage.vue +62 -0
  17. package/src/components/LkMaterialLayer.vue +147 -0
  18. package/src/components/LkMenuItem.vue +51 -0
  19. package/src/components/LkNavbar.vue +113 -0
  20. package/src/components/LkPlaceholderBlock.vue +9 -0
  21. package/src/components/LkRow.vue +40 -0
  22. package/src/components/LkSection.vue +45 -0
  23. package/src/components/LkSelect.vue +167 -0
  24. package/src/components/LkSelectMenu.vue +67 -0
  25. package/src/components/LkSelectOption.vue +56 -0
  26. package/src/components/LkSelectTrigger.vue +43 -0
  27. package/src/components/LkSnackbar.vue +127 -0
  28. package/src/components/LkStateLayer.vue +33 -0
  29. package/src/components/LkSticker.vue +42 -0
  30. package/src/components/LkSwitch.vue +90 -0
  31. package/src/components/LkTabContent.vue +33 -0
  32. package/src/components/LkTabLink.vue +50 -0
  33. package/src/components/LkTabMenu.vue +59 -0
  34. package/src/components/LkTabs.vue +65 -0
  35. package/src/components/LkText.vue +37 -0
  36. package/src/components/LkTextInput.vue +105 -0
  37. package/src/components/LkTheme.vue +49 -0
  38. package/src/components/LkThemeController.vue +396 -0
  39. package/src/css/index.css +3 -1
  40. package/src/css/liftkit-core.css +5 -464
  41. package/src/css/liftkit-reset.css +74 -0
  42. package/src/css/liftkit-tokens.css +375 -0
@@ -0,0 +1,50 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { propsToDataAttrs } from '../utils/utilities'
4
+ import LkText from './LkText.vue'
5
+
6
+ export interface LkTabLinkProps {
7
+ selected?: boolean
8
+ fontClass?: LkFontClass
9
+ indicatorClass?: string
10
+ }
11
+
12
+ const props = withDefaults(defineProps<LkTabLinkProps>(), {
13
+ selected: false,
14
+ fontClass: 'body',
15
+ indicatorClass: 'lk-indicator',
16
+ })
17
+
18
+ defineOptions({
19
+ inheritAttrs: false,
20
+ })
21
+
22
+ const dataAttrs = computed(() =>
23
+ propsToDataAttrs(
24
+ {
25
+ selected: props.selected,
26
+ fontClass: props.fontClass,
27
+ indicatorClass: props.indicatorClass,
28
+ },
29
+ 'tab-link',
30
+ ),
31
+ )
32
+
33
+ const textStyle = computed(() =>
34
+ props.selected ? { fontWeight: 700 } : {},
35
+ )
36
+ </script>
37
+
38
+ <template>
39
+ <div
40
+ data-lk-component="tab-link"
41
+ v-bind="{ ...$attrs, ...dataAttrs }"
42
+ >
43
+ <div data-lk-slot="child">
44
+ <LkText :font-class="fontClass" :style="textStyle">
45
+ <slot />
46
+ </LkText>
47
+ </div>
48
+ <div :class="indicatorClass" />
49
+ </div>
50
+ </template>
@@ -0,0 +1,59 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { propsToDataAttrs } from '../utils/utilities'
4
+ import LkRow from './LkRow.vue'
5
+ import LkTabLink from './LkTabLink.vue'
6
+
7
+ export interface LkTabMenuProps {
8
+ tabLinks?: string[]
9
+ alignItems?: 'start' | 'center' | 'end' | 'stretch'
10
+ justifyContent?: 'start' | 'center' | 'end' | 'space-between' | 'space-around'
11
+ activeTab?: number
12
+ }
13
+
14
+ const props = withDefaults(defineProps<LkTabMenuProps>(), {
15
+ tabLinks: () => ['Tab Link 1', 'Tab Link 2', 'Tab Link 3'],
16
+ activeTab: 0,
17
+ })
18
+
19
+ const emit = defineEmits<{
20
+ 'update:activeTab': [index: number]
21
+ }>()
22
+
23
+ defineOptions({
24
+ inheritAttrs: false,
25
+ })
26
+
27
+ const dataAttrs = computed(() =>
28
+ propsToDataAttrs(
29
+ {
30
+ alignItems: props.alignItems,
31
+ justifyContent: props.justifyContent,
32
+ activeTab: props.activeTab,
33
+ },
34
+ 'tab-menu',
35
+ ),
36
+ )
37
+
38
+ function handleTabClick(index: number) {
39
+ emit('update:activeTab', index)
40
+ }
41
+ </script>
42
+
43
+ <template>
44
+ <div
45
+ data-lk-component="tab-menu"
46
+ v-bind="{ ...$attrs, ...dataAttrs }"
47
+ >
48
+ <LkRow :align-items="alignItems" :justify-content="justifyContent">
49
+ <LkTabLink
50
+ v-for="(label, index) in tabLinks"
51
+ :key="index"
52
+ :selected="index === activeTab"
53
+ @click="handleTabClick(index)"
54
+ >
55
+ <div>{{ label ?? 'Tab Link' }}</div>
56
+ </LkTabLink>
57
+ </LkRow>
58
+ </div>
59
+ </template>
@@ -0,0 +1,65 @@
1
+ <script setup lang="ts">
2
+ import { ref, computed, watch, provide } from 'vue'
3
+ import { propsToDataAttrs } from '../utils/utilities'
4
+ import LkTabMenu from './LkTabMenu.vue'
5
+
6
+ export interface LkTabsProps {
7
+ tabLinks: string[]
8
+ scrollableContent?: boolean
9
+ defaultTab?: number
10
+ }
11
+
12
+ const props = withDefaults(defineProps<LkTabsProps>(), {
13
+ scrollableContent: false,
14
+ defaultTab: 0,
15
+ })
16
+
17
+ const emit = defineEmits<{
18
+ 'activeTabChange': [index: number]
19
+ }>()
20
+
21
+ defineOptions({
22
+ inheritAttrs: false,
23
+ })
24
+
25
+ const activeTab = ref(props.defaultTab)
26
+
27
+ function setActiveTab(index: number) {
28
+ activeTab.value = index
29
+ }
30
+
31
+ watch(activeTab, (newVal) => {
32
+ emit('activeTabChange', newVal)
33
+ })
34
+
35
+ provide('lk-tabs', {
36
+ activeTab,
37
+ setActiveTab,
38
+ })
39
+
40
+ const dataAttrs = computed(() =>
41
+ propsToDataAttrs({ activeTab: activeTab.value }, 'tabs'),
42
+ )
43
+ </script>
44
+
45
+ <template>
46
+ <div
47
+ data-lk-component="tabs"
48
+ :data-lk-tabs-content-scrollable="scrollableContent || undefined"
49
+ v-bind="{ ...$attrs, ...dataAttrs }"
50
+ >
51
+ <LkTabMenu
52
+ :tab-links="tabLinks"
53
+ justify-content="start"
54
+ align-items="stretch"
55
+ :active-tab="activeTab"
56
+ @update:active-tab="setActiveTab"
57
+ />
58
+ <div
59
+ data-lk-tabs-el="tab-content"
60
+ :data-lk-tabs-content-scrollable="scrollableContent || undefined"
61
+ >
62
+ <slot :active-tab="activeTab" />
63
+ </div>
64
+ </div>
65
+ </template>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ interface LkTextProps {
5
+ tag?: string
6
+ fontClass?: LkFontClass
7
+ color?: LkColor
8
+ class?: string
9
+ }
10
+
11
+ const props = withDefaults(defineProps<LkTextProps>(), {
12
+ tag: 'div',
13
+ })
14
+
15
+ defineOptions({
16
+ inheritAttrs: false,
17
+ })
18
+
19
+ const textClass = computed(() => {
20
+ const classes: string[] = []
21
+ if (props.fontClass) classes.push(props.fontClass)
22
+ if (props.color) classes.push(`color-${props.color}`)
23
+ if (props.class) classes.push(props.class)
24
+ return classes.join(' ')
25
+ })
26
+ </script>
27
+
28
+ <template>
29
+ <component
30
+ :is="props.tag"
31
+ data-lk-component="text"
32
+ :class="textClass"
33
+ v-bind="$attrs"
34
+ >
35
+ <slot />
36
+ </component>
37
+ </template>
@@ -0,0 +1,105 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { propsToDataAttrs } from '../utils/utilities'
4
+ import LkIcon from './LkIcon.vue'
5
+ import LkStateLayer from './LkStateLayer.vue'
6
+ import LkRow from './LkRow.vue'
7
+ import LkText from './LkText.vue'
8
+
9
+ export interface LkTextInputProps {
10
+ modelValue?: string
11
+ labelPosition?: 'default' | 'on-input'
12
+ helpText?: string
13
+ placeholder?: string
14
+ name?: string
15
+ endIcon?: string
16
+ labelBackgroundColor?: LkColor
17
+ }
18
+
19
+ const props = withDefaults(defineProps<LkTextInputProps>(), {
20
+ modelValue: '',
21
+ labelPosition: 'default',
22
+ placeholder: 'Placeholder',
23
+ name: 'Label',
24
+ endIcon: 'search',
25
+ })
26
+
27
+ const emit = defineEmits<{
28
+ 'update:modelValue': [value: string]
29
+ }>()
30
+
31
+ defineOptions({
32
+ inheritAttrs: false,
33
+ })
34
+
35
+ const textInputAttrs = computed(() =>
36
+ propsToDataAttrs({ labelPosition: props.labelPosition }, 'text-input'),
37
+ )
38
+
39
+ function onInput(event: Event) {
40
+ const target = event.target as HTMLInputElement
41
+ emit('update:modelValue', target.value)
42
+ }
43
+
44
+ const onInputLabelClass = computed(() => {
45
+ let cls = 'body'
46
+ if (props.labelBackgroundColor) {
47
+ cls += ` bg-${props.labelBackgroundColor}`
48
+ }
49
+ if (props.modelValue) {
50
+ cls += ' on-field-with-value-set'
51
+ }
52
+ return cls
53
+ })
54
+ </script>
55
+
56
+ <template>
57
+ <div
58
+ data-lk-component="text-input"
59
+ v-bind="{ ...$attrs, ...textInputAttrs }"
60
+ >
61
+ <label
62
+ v-if="labelPosition === 'default'"
63
+ :for="name"
64
+ class="label"
65
+ >
66
+ {{ name }}
67
+ </label>
68
+
69
+ <div
70
+ data-lk-text-input-el="input-wrap"
71
+ :data-lk-input-help-text="helpText ? 'true' : 'false'"
72
+ :data-help-text="helpText"
73
+ >
74
+ <label
75
+ v-if="labelPosition === 'on-input'"
76
+ :for="name"
77
+ :class="onInputLabelClass"
78
+ >
79
+ {{ name }}
80
+ </label>
81
+ <input
82
+ type="text"
83
+ :name="name"
84
+ :id="name"
85
+ :placeholder="labelPosition !== 'on-input' ? placeholder : ''"
86
+ :value="modelValue"
87
+ @input="onInput"
88
+ />
89
+ <LkStateLayer />
90
+ <LkIcon :name="endIcon" />
91
+ </div>
92
+
93
+ <LkRow v-if="helpText" align-items="center">
94
+ <LkIcon
95
+ name="info"
96
+ font-class="capline"
97
+ color="outline"
98
+ :optic-shift="true"
99
+ />
100
+ <LkText color="outline" font-class="caption" class="m-left-2xs">
101
+ Help text goes here
102
+ </LkText>
103
+ </LkRow>
104
+ </div>
105
+ </template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+ import { provideTheme, type PaletteState, type ColorModePreference } from '../composables'
4
+
5
+ export interface LkThemeProps {
6
+ /** Source/seed color to generate theme from (hex) */
7
+ sourceColor?: string
8
+ /** Color mode - 'auto' follows OS setting, 'light'/'dark' forces mode */
9
+ colorMode?: ColorModePreference
10
+ /** Custom initial palette overrides */
11
+ palette?: Partial<PaletteState>
12
+ }
13
+
14
+ const props = withDefaults(defineProps<LkThemeProps>(), {
15
+ sourceColor: undefined,
16
+ colorMode: 'auto',
17
+ palette: undefined,
18
+ })
19
+
20
+ // Build the initial palette from props
21
+ const initialPalette = computed<Partial<PaletteState>>(() => {
22
+ const pal: Partial<PaletteState> = {}
23
+ if (props.palette) {
24
+ Object.assign(pal, props.palette)
25
+ }
26
+ return pal
27
+ })
28
+
29
+ // Provide theme context to all children
30
+ const theme = provideTheme(initialPalette.value)
31
+
32
+ // Set the initial color mode preference
33
+ theme.setColorMode(props.colorMode)
34
+
35
+ // If sourceColor is provided, generate theme from it
36
+ if (props.sourceColor) {
37
+ theme.updateThemeFromMaster(props.sourceColor)
38
+ }
39
+
40
+ defineExpose({
41
+ theme,
42
+ })
43
+ </script>
44
+
45
+ <template>
46
+ <div class="lk-theme" v-bind="$attrs">
47
+ <slot />
48
+ </div>
49
+ </template>