design-system-next 2.11.20 → 2.12.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.
- package/dist/design-system-next.es.js +7837 -7514
- package/dist/design-system-next.es.js.gz +0 -0
- package/dist/design-system-next.umd.js +12 -12
- package/dist/design-system-next.umd.js.gz +0 -0
- package/dist/main.css +1 -1
- package/dist/main.css.gz +0 -0
- package/dist/package.json.d.ts +1 -1
- package/package.json +1 -1
- package/src/App.vue +1 -49
- package/src/assets/scripts/border-radius.ts +15 -15
- package/src/assets/scripts/colors.ts +134 -134
- package/src/assets/scripts/max-width.ts +11 -11
- package/src/assets/scripts/spacing.ts +23 -23
- package/src/assets/scripts/utilities.ts +15 -15
- package/src/components/accordion/accordion.ts +43 -43
- package/src/components/accordion/use-accordion.ts +43 -43
- package/src/components/avatar/avatar.ts +64 -64
- package/src/components/badge/badge.ts +43 -43
- package/src/components/banner/banner.ts +20 -20
- package/src/components/button/button.ts +72 -72
- package/src/components/button/button.vue +15 -15
- package/src/components/card/card.ts +52 -52
- package/src/components/checkbox/checkbox.ts +45 -45
- package/src/components/chips/chips.ts +95 -95
- package/src/components/collapsible/collapsible.ts +21 -21
- package/src/components/collapsible/collapsible.vue +27 -27
- package/src/components/date-picker/__tests__/date-picker.test.ts +112 -112
- package/src/components/date-picker/date-picker.ts +157 -157
- package/src/components/date-picker/date-picker.vue +60 -53
- package/src/components/date-picker/use-date-picker.ts +6 -0
- package/src/components/dropdown/__tests__/dropdown-fixes.spec.ts +106 -106
- package/src/components/dropdown/__tests__/dropdown-value-types.spec.ts +213 -213
- package/src/components/dropdown/fix-multi-number.ts +92 -92
- package/src/components/dropdown/use-dropdown.ts +488 -488
- package/src/components/empty-state/empty-state.ts +50 -50
- package/src/components/file-upload/file-upload.ts +87 -87
- package/src/components/floating-action/floating-action.ts +12 -12
- package/src/components/input/input-contact-number/input-contact-number.ts +83 -83
- package/src/components/input/input-email/input-email.vue +17 -17
- package/src/components/input/input-password/use-input-password.ts +19 -19
- package/src/components/input/input-search/input-search.vue +13 -13
- package/src/components/input/input-url/input-url.vue +20 -20
- package/src/components/input/input-username/input-username.vue +17 -17
- package/src/components/input/input.vue +72 -72
- package/src/components/list/ladderized-list/ladderized-list.ts +39 -39
- package/src/components/logo/logo.ts +43 -43
- package/src/components/logo/logo.vue +14 -14
- package/src/components/logo/use-logo.ts +41 -41
- package/src/components/lozenge/lozenge.ts +16 -0
- package/src/components/lozenge/lozenge.vue +22 -13
- package/src/components/lozenge/use-lozenge.ts +58 -27
- package/src/components/modal/modal.ts +45 -45
- package/src/components/progress-bar/progress-bar.ts +39 -39
- package/src/components/radio/radio.ts +42 -42
- package/src/components/select/select.ts +144 -144
- package/src/components/sidenav/sidenav.ts +14 -0
- package/src/components/sidenav/sidenav.vue +36 -6
- package/src/components/sidenav/use-sidenav.ts +16 -3
- package/src/components/sidepanel/sidepanel.vue +55 -55
- package/src/components/sidepanel/stacking-sidepanel/stacking-sidepanel.ts +16 -16
- package/src/components/sidepanel/stacking-sidepanel/stacking-sidepanel.vue +39 -39
- package/src/components/slider/slider.ts +38 -38
- package/src/components/snackbar/snack/snack.ts +71 -71
- package/src/components/snackbar/use-snackbar.ts +34 -34
- package/src/components/status/status.ts +19 -19
- package/src/components/status/status.vue +13 -13
- package/src/components/stepper/step/step.ts +47 -47
- package/src/components/stepper/stepper.ts +47 -47
- package/src/components/stepper/stepper.vue +34 -34
- package/src/components/switch/switch.ts +42 -42
- package/src/components/table/table-actions/table-actions.ts +42 -42
- package/src/components/table/table-actions/table-actions.vue +40 -40
- package/src/components/table/table-chips-title/table-chips-title.ts +27 -27
- package/src/components/table/table-chips-title/table-chips-title.vue +32 -32
- package/src/components/table/table-chips-title/use-table-chips-title.ts +22 -22
- package/src/components/table/table-lozenge-title/table-lozenge-title.ts +23 -23
- package/src/components/table/table-lozenge-title/table-lozenge-title.vue +26 -26
- package/src/components/table/table-lozenge-title/use-table-lozenge-title.ts +21 -21
- package/src/components/table/table-pagination/table-pagination.ts +63 -63
- package/src/components/table/table-pagination/table-pagination.vue +72 -72
- package/src/components/table/table.ts +173 -173
- package/src/components/tabs/tabs.ts +43 -43
- package/src/components/textarea/textarea.ts +72 -72
- package/src/components/textarea/textarea.vue +45 -45
- package/src/components/time-picker/time-picker.ts +69 -69
- package/src/components/tooltip/use-tooltip.ts +13 -13
- package/src/examples/dropdown-number-multi-select.vue +76 -76
- package/src/stores/useSnackbarStore.ts +44 -44
- package/src/vite-env.d.ts +6 -0
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div :class="inputClasses.baseClasses">
|
|
3
|
-
<label v-if="props.label" :for="id" :class="inputClasses.labelClasses">
|
|
4
|
-
{{ props.label }}
|
|
5
|
-
</label>
|
|
6
|
-
|
|
7
|
-
<div :class="inputClasses.inputTextBaseClasses">
|
|
8
|
-
<div v-if="$slots.prefix" :class="inputClasses.prefixSlotClasses">
|
|
9
|
-
<slot name="prefix" />
|
|
10
|
-
</div>
|
|
11
|
-
<input
|
|
12
|
-
v-bind="$attrs"
|
|
13
|
-
:id="props.id"
|
|
14
|
-
ref="inputTextRef"
|
|
15
|
-
:class="[inputClasses.inputTextClasses, { 'number-input': props.type === 'number' }]"
|
|
16
|
-
:placeholder="props.placeholder"
|
|
17
|
-
:type="props.type"
|
|
18
|
-
:minlength="props.minLength"
|
|
19
|
-
:maxlength="props.maxLength"
|
|
20
|
-
:value="modelValue"
|
|
21
|
-
:disabled="props.disabled"
|
|
22
|
-
:readonly="props.readonly"
|
|
23
|
-
@input="onInput"
|
|
24
|
-
/>
|
|
25
|
-
<div v-if="$slots.trailing" :class="inputClasses.trailingSlotClasses">
|
|
26
|
-
<slot name="trailing" />
|
|
27
|
-
</div>
|
|
28
|
-
<div v-if="$slots.icon" :class="inputClasses.iconSlotClasses" @click="disableClickEvent">
|
|
29
|
-
<slot name="icon" />
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
<div v-if="props.displayHelper || props.showCharCount" :class="inputClasses.helperContainerClasses">
|
|
34
|
-
<div v-if="props.displayHelper" :class="inputClasses.helperClasses">
|
|
35
|
-
<slot name="helperMessage">
|
|
36
|
-
<Icon v-if="props.helperIcon" :icon="props.helperIcon" width="20px" height="20px" />
|
|
37
|
-
<span>{{ props.helperText }}</span>
|
|
38
|
-
</slot>
|
|
39
|
-
</div>
|
|
40
|
-
<div v-if="props.showCharCount" :class="inputClasses.charCountClasses">
|
|
41
|
-
{{ currentLength }}{{ props.maxLength ? '/' + props.maxLength : '' }}
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
</template>
|
|
46
|
-
|
|
47
|
-
<script setup lang="ts">
|
|
48
|
-
import { useSlots } from 'vue';
|
|
49
|
-
|
|
50
|
-
import { Icon } from '@iconify/vue';
|
|
51
|
-
|
|
52
|
-
import { inputPropTypes, inputEmitTypes } from './input';
|
|
53
|
-
import { useInput } from './use-input';
|
|
54
|
-
|
|
55
|
-
const emit = defineEmits(inputEmitTypes);
|
|
56
|
-
const props = defineProps(inputPropTypes);
|
|
57
|
-
const slots = useSlots();
|
|
58
|
-
|
|
59
|
-
const { inputClasses, inputTextRef, onInput, disableClickEvent, currentLength } = useInput(props, emit, slots);
|
|
60
|
-
</script>
|
|
61
|
-
|
|
62
|
-
<style scoped>
|
|
63
|
-
.number-input::-webkit-outer-spin-button,
|
|
64
|
-
.number-input::-webkit-inner-spin-button {
|
|
65
|
-
margin: 0;
|
|
66
|
-
-webkit-appearance: none;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.number-input {
|
|
70
|
-
-moz-appearance: textfield;
|
|
71
|
-
}
|
|
72
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="inputClasses.baseClasses">
|
|
3
|
+
<label v-if="props.label" :for="id" :class="inputClasses.labelClasses">
|
|
4
|
+
{{ props.label }}
|
|
5
|
+
</label>
|
|
6
|
+
|
|
7
|
+
<div :class="inputClasses.inputTextBaseClasses">
|
|
8
|
+
<div v-if="$slots.prefix" :class="inputClasses.prefixSlotClasses">
|
|
9
|
+
<slot name="prefix" />
|
|
10
|
+
</div>
|
|
11
|
+
<input
|
|
12
|
+
v-bind="$attrs"
|
|
13
|
+
:id="props.id"
|
|
14
|
+
ref="inputTextRef"
|
|
15
|
+
:class="[inputClasses.inputTextClasses, { 'number-input': props.type === 'number' }]"
|
|
16
|
+
:placeholder="props.placeholder"
|
|
17
|
+
:type="props.type"
|
|
18
|
+
:minlength="props.minLength"
|
|
19
|
+
:maxlength="props.maxLength"
|
|
20
|
+
:value="modelValue"
|
|
21
|
+
:disabled="props.disabled"
|
|
22
|
+
:readonly="props.readonly"
|
|
23
|
+
@input="onInput"
|
|
24
|
+
/>
|
|
25
|
+
<div v-if="$slots.trailing" :class="inputClasses.trailingSlotClasses">
|
|
26
|
+
<slot name="trailing" />
|
|
27
|
+
</div>
|
|
28
|
+
<div v-if="$slots.icon" :class="inputClasses.iconSlotClasses" @click="disableClickEvent">
|
|
29
|
+
<slot name="icon" />
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div v-if="props.displayHelper || props.showCharCount" :class="inputClasses.helperContainerClasses">
|
|
34
|
+
<div v-if="props.displayHelper" :class="inputClasses.helperClasses">
|
|
35
|
+
<slot name="helperMessage">
|
|
36
|
+
<Icon v-if="props.helperIcon" :icon="props.helperIcon" width="20px" height="20px" />
|
|
37
|
+
<span>{{ props.helperText }}</span>
|
|
38
|
+
</slot>
|
|
39
|
+
</div>
|
|
40
|
+
<div v-if="props.showCharCount" :class="inputClasses.charCountClasses">
|
|
41
|
+
{{ currentLength }}{{ props.maxLength ? '/' + props.maxLength : '' }}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<script setup lang="ts">
|
|
48
|
+
import { useSlots } from 'vue';
|
|
49
|
+
|
|
50
|
+
import { Icon } from '@iconify/vue';
|
|
51
|
+
|
|
52
|
+
import { inputPropTypes, inputEmitTypes } from './input';
|
|
53
|
+
import { useInput } from './use-input';
|
|
54
|
+
|
|
55
|
+
const emit = defineEmits(inputEmitTypes);
|
|
56
|
+
const props = defineProps(inputPropTypes);
|
|
57
|
+
const slots = useSlots();
|
|
58
|
+
|
|
59
|
+
const { inputClasses, inputTextRef, onInput, disableClickEvent, currentLength } = useInput(props, emit, slots);
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<style scoped>
|
|
63
|
+
.number-input::-webkit-outer-spin-button,
|
|
64
|
+
.number-input::-webkit-inner-spin-button {
|
|
65
|
+
margin: 0;
|
|
66
|
+
-webkit-appearance: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.number-input {
|
|
70
|
+
-moz-appearance: textfield;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
-
import { MenuListType } from '../list';
|
|
3
|
-
export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<T>;
|
|
4
|
-
|
|
5
|
-
export const ladderizedListPropTypes = {
|
|
6
|
-
modelValue: {
|
|
7
|
-
type: Array as PropType<string[]>,
|
|
8
|
-
required: true,
|
|
9
|
-
default: [],
|
|
10
|
-
},
|
|
11
|
-
menuList: {
|
|
12
|
-
type: Array as PropType<MenuListType[]>,
|
|
13
|
-
required: true,
|
|
14
|
-
default: [],
|
|
15
|
-
},
|
|
16
|
-
menuLevel: {
|
|
17
|
-
type: Number,
|
|
18
|
-
default: 0,
|
|
19
|
-
},
|
|
20
|
-
searchableMenu: {
|
|
21
|
-
type: Boolean,
|
|
22
|
-
default: false,
|
|
23
|
-
},
|
|
24
|
-
searchableMenuPlaceholder: {
|
|
25
|
-
type: String,
|
|
26
|
-
default: 'Search...',
|
|
27
|
-
},
|
|
28
|
-
removeCurrentLevelInBackLabel: {
|
|
29
|
-
type: Boolean,
|
|
30
|
-
default: false,
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const ladderizedListEmitTypes = {
|
|
35
|
-
'update:modelValue': (value: string[]) => value,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export type LadderizedListPropTypes = ExtractPropTypes<typeof ladderizedListPropTypes>;
|
|
39
|
-
export type LadderizedListEmitTypes = typeof ladderizedListEmitTypes;
|
|
1
|
+
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
+
import { MenuListType } from '../list';
|
|
3
|
+
export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<T>;
|
|
4
|
+
|
|
5
|
+
export const ladderizedListPropTypes = {
|
|
6
|
+
modelValue: {
|
|
7
|
+
type: Array as PropType<string[]>,
|
|
8
|
+
required: true,
|
|
9
|
+
default: [],
|
|
10
|
+
},
|
|
11
|
+
menuList: {
|
|
12
|
+
type: Array as PropType<MenuListType[]>,
|
|
13
|
+
required: true,
|
|
14
|
+
default: [],
|
|
15
|
+
},
|
|
16
|
+
menuLevel: {
|
|
17
|
+
type: Number,
|
|
18
|
+
default: 0,
|
|
19
|
+
},
|
|
20
|
+
searchableMenu: {
|
|
21
|
+
type: Boolean,
|
|
22
|
+
default: false,
|
|
23
|
+
},
|
|
24
|
+
searchableMenuPlaceholder: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: 'Search...',
|
|
27
|
+
},
|
|
28
|
+
removeCurrentLevelInBackLabel: {
|
|
29
|
+
type: Boolean,
|
|
30
|
+
default: false,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const ladderizedListEmitTypes = {
|
|
35
|
+
'update:modelValue': (value: string[]) => value,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type LadderizedListPropTypes = ExtractPropTypes<typeof ladderizedListPropTypes>;
|
|
39
|
+
export type LadderizedListEmitTypes = typeof ladderizedListEmitTypes;
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
-
|
|
3
|
-
const LOGO_THEMES = ['white', 'dark', 'gray', 'green'] as const;
|
|
4
|
-
const LOGO_NAMES = [
|
|
5
|
-
'benchmark',
|
|
6
|
-
'ecosystem',
|
|
7
|
-
'engage',
|
|
8
|
-
'finances',
|
|
9
|
-
'hr-mobile',
|
|
10
|
-
'hr',
|
|
11
|
-
'inbound',
|
|
12
|
-
'insight',
|
|
13
|
-
'readycash',
|
|
14
|
-
'readywage',
|
|
15
|
-
'payroll',
|
|
16
|
-
'performance-plus',
|
|
17
|
-
'procurement',
|
|
18
|
-
'professional-services',
|
|
19
|
-
'recruit',
|
|
20
|
-
'recruit-plus',
|
|
21
|
-
'sail',
|
|
22
|
-
'sidekick',
|
|
23
|
-
'wellness',
|
|
24
|
-
] as const;
|
|
25
|
-
|
|
26
|
-
export const logoPropTypes = {
|
|
27
|
-
name: {
|
|
28
|
-
type: String as PropType<(typeof LOGO_NAMES)[number]>,
|
|
29
|
-
validator: (value: (typeof LOGO_NAMES)[number]) => LOGO_NAMES.includes(value),
|
|
30
|
-
default: 'hr',
|
|
31
|
-
},
|
|
32
|
-
theme: {
|
|
33
|
-
type: String as PropType<(typeof LOGO_THEMES)[number]>,
|
|
34
|
-
validator: (value: (typeof LOGO_THEMES)[number]) => LOGO_THEMES.includes(value),
|
|
35
|
-
default: 'dark',
|
|
36
|
-
},
|
|
37
|
-
width: {
|
|
38
|
-
type: [String, Number] as PropType<string | number>,
|
|
39
|
-
default: '50', // If number, it will be treated as px
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export type LogoPropTypes = ExtractPropTypes<typeof logoPropTypes>;
|
|
1
|
+
import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
+
|
|
3
|
+
const LOGO_THEMES = ['white', 'dark', 'gray', 'green'] as const;
|
|
4
|
+
const LOGO_NAMES = [
|
|
5
|
+
'benchmark',
|
|
6
|
+
'ecosystem',
|
|
7
|
+
'engage',
|
|
8
|
+
'finances',
|
|
9
|
+
'hr-mobile',
|
|
10
|
+
'hr',
|
|
11
|
+
'inbound',
|
|
12
|
+
'insight',
|
|
13
|
+
'readycash',
|
|
14
|
+
'readywage',
|
|
15
|
+
'payroll',
|
|
16
|
+
'performance-plus',
|
|
17
|
+
'procurement',
|
|
18
|
+
'professional-services',
|
|
19
|
+
'recruit',
|
|
20
|
+
'recruit-plus',
|
|
21
|
+
'sail',
|
|
22
|
+
'sidekick',
|
|
23
|
+
'wellness',
|
|
24
|
+
] as const;
|
|
25
|
+
|
|
26
|
+
export const logoPropTypes = {
|
|
27
|
+
name: {
|
|
28
|
+
type: String as PropType<(typeof LOGO_NAMES)[number]>,
|
|
29
|
+
validator: (value: (typeof LOGO_NAMES)[number]) => LOGO_NAMES.includes(value),
|
|
30
|
+
default: 'hr',
|
|
31
|
+
},
|
|
32
|
+
theme: {
|
|
33
|
+
type: String as PropType<(typeof LOGO_THEMES)[number]>,
|
|
34
|
+
validator: (value: (typeof LOGO_THEMES)[number]) => LOGO_THEMES.includes(value),
|
|
35
|
+
default: 'dark',
|
|
36
|
+
},
|
|
37
|
+
width: {
|
|
38
|
+
type: [String, Number] as PropType<string | number>,
|
|
39
|
+
default: '50', // If number, it will be treated as px
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type LogoPropTypes = ExtractPropTypes<typeof logoPropTypes>;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<img v-bind="$attrs" :src="logoSrc" :alt="logoTitle" :title="logoTitle" :width="width" />
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script lang="ts" setup>
|
|
8
|
-
import { useLogo } from './use-logo';
|
|
9
|
-
import { logoPropTypes } from './logo';
|
|
10
|
-
|
|
11
|
-
const props = defineProps(logoPropTypes);
|
|
12
|
-
|
|
13
|
-
const { logoSrc, logoTitle } = useLogo(props);
|
|
14
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<img v-bind="$attrs" :src="logoSrc" :alt="logoTitle" :title="logoTitle" :width="width" />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts" setup>
|
|
8
|
+
import { useLogo } from './use-logo';
|
|
9
|
+
import { logoPropTypes } from './logo';
|
|
10
|
+
|
|
11
|
+
const props = defineProps(logoPropTypes);
|
|
12
|
+
|
|
13
|
+
const { logoSrc, logoTitle } = useLogo(props);
|
|
14
|
+
</script>
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { computed } from 'vue';
|
|
2
|
-
import type { LogoPropTypes } from './logo';
|
|
3
|
-
import { Cloudinary } from '@cloudinary/url-gen';
|
|
4
|
-
|
|
5
|
-
const CLOUD_NAME = 'dfeykvudc';
|
|
6
|
-
|
|
7
|
-
const NAME_MAP: Record<string, string> = {
|
|
8
|
-
'hr': 'Sprout HR',
|
|
9
|
-
'hr-mobile': 'Sprout HR Mobile',
|
|
10
|
-
'performance-plus': 'Sprout Performance+',
|
|
11
|
-
'recruit-plus': 'Sprout Recruit+',
|
|
12
|
-
'sail': 'Sprout SAIL',
|
|
13
|
-
'readycash': 'Sprout ReadyCash',
|
|
14
|
-
'readywage': 'Sprout ReadyWage',
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export function useLogo(props: LogoPropTypes) {
|
|
18
|
-
const cld = new Cloudinary({
|
|
19
|
-
cloud: {
|
|
20
|
-
cloudName: CLOUD_NAME,
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const logoSrc = computed(() => cld.image(`sprout-${props.name}-${props.theme}`).toURL());
|
|
25
|
-
|
|
26
|
-
const logoTitle = computed(() => {
|
|
27
|
-
if (props.name in NAME_MAP) {
|
|
28
|
-
return NAME_MAP[props.name];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const firstChar = props.name.charAt(0).toUpperCase();
|
|
32
|
-
const remainingChars = props.name.slice(1);
|
|
33
|
-
const formattedName = `${firstChar}${remainingChars}`;
|
|
34
|
-
return `Sprout ${formattedName}`;
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
logoSrc,
|
|
39
|
-
logoTitle,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
import type { LogoPropTypes } from './logo';
|
|
3
|
+
import { Cloudinary } from '@cloudinary/url-gen';
|
|
4
|
+
|
|
5
|
+
const CLOUD_NAME = 'dfeykvudc';
|
|
6
|
+
|
|
7
|
+
const NAME_MAP: Record<string, string> = {
|
|
8
|
+
'hr': 'Sprout HR',
|
|
9
|
+
'hr-mobile': 'Sprout HR Mobile',
|
|
10
|
+
'performance-plus': 'Sprout Performance+',
|
|
11
|
+
'recruit-plus': 'Sprout Recruit+',
|
|
12
|
+
'sail': 'Sprout SAIL',
|
|
13
|
+
'readycash': 'Sprout ReadyCash',
|
|
14
|
+
'readywage': 'Sprout ReadyWage',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function useLogo(props: LogoPropTypes) {
|
|
18
|
+
const cld = new Cloudinary({
|
|
19
|
+
cloud: {
|
|
20
|
+
cloudName: CLOUD_NAME,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const logoSrc = computed(() => cld.image(`sprout-${props.name}-${props.theme}`).toURL());
|
|
25
|
+
|
|
26
|
+
const logoTitle = computed(() => {
|
|
27
|
+
if (props.name in NAME_MAP) {
|
|
28
|
+
return NAME_MAP[props.name];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const firstChar = props.name.charAt(0).toUpperCase();
|
|
32
|
+
const remainingChars = props.name.slice(1);
|
|
33
|
+
const formattedName = `${firstChar}${remainingChars}`;
|
|
34
|
+
return `Sprout ${formattedName}`;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
logoSrc,
|
|
39
|
+
logoTitle,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -52,6 +52,22 @@ export const lozengePropTypes = {
|
|
|
52
52
|
type: Boolean,
|
|
53
53
|
default: false,
|
|
54
54
|
},
|
|
55
|
+
icon: {
|
|
56
|
+
type: String,
|
|
57
|
+
default: '',
|
|
58
|
+
},
|
|
59
|
+
postfixIcon: {
|
|
60
|
+
type: String,
|
|
61
|
+
default: '',
|
|
62
|
+
},
|
|
63
|
+
interactive: {
|
|
64
|
+
type: Boolean,
|
|
65
|
+
default: false,
|
|
66
|
+
},
|
|
67
|
+
dropdown: {
|
|
68
|
+
type: Boolean,
|
|
69
|
+
default: false,
|
|
70
|
+
},
|
|
55
71
|
};
|
|
56
72
|
|
|
57
73
|
export type LozengePropTypes = ExtractPropTypes<typeof lozengePropTypes>;
|
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="lozengeClasses.wrapperClasses">
|
|
3
|
-
<div v-if="visible && !loading" :class="lozengeClasses.baseClasses">
|
|
4
|
-
<div :class="lozengeClasses.toneClasses">
|
|
5
|
-
<div v-if="$slots.icon" class="spr-flex spr-h-3 spr-w-3 spr-items-center spr-overflow-hidden">
|
|
6
|
-
<slot name="icon"
|
|
2
|
+
<div :class="['spr-lozenge__wrapper', lozengeClasses.wrapperClasses]">
|
|
3
|
+
<div v-if="visible && !loading" :class="['spr-lozenge__base', lozengeClasses.baseClasses]">
|
|
4
|
+
<div :class="['spr-lozenge__tone',lozengeClasses.toneClasses]" :tabindex="props.interactive || props.dropdown ? 0 : -1">
|
|
5
|
+
<div v-if="$slots.icon || props.icon" class="spr-lozenge__prefix-icon spr-flex spr-h-3 spr-w-3 spr-items-center spr-overflow-hidden">
|
|
6
|
+
<slot name="icon">
|
|
7
|
+
<icon :icon="props.icon" />
|
|
8
|
+
</slot>
|
|
7
9
|
</div>
|
|
8
10
|
|
|
9
|
-
<div v-if="$slots.avatar" class="spr-
|
|
10
|
-
<slot name="avatar"
|
|
11
|
+
<div v-if="$slots.avatar || props.url" class="spr-lozenge__avatar">
|
|
12
|
+
<slot name="avatar">
|
|
13
|
+
<div v-if="url" class="spr-h-4 spr-w-4 spr-overflow-hidden">
|
|
14
|
+
<img class="spr-h-full spr-w-full spr-rounded-full spr-object-cover" :src="url" alt="avatar" />
|
|
15
|
+
</div>
|
|
16
|
+
</slot>
|
|
11
17
|
</div>
|
|
12
18
|
|
|
13
|
-
<
|
|
14
|
-
<img class="spr-h-full spr-w-full spr-rounded-full spr-object-cover" :src="url" alt="avatar" />
|
|
15
|
-
</div>
|
|
19
|
+
<span class="spr-lozenge__label spr-label-xs-medium">{{ label }}</span>
|
|
16
20
|
|
|
17
|
-
<div
|
|
21
|
+
<div v-if="$slots.postfixIcon || props.postfixIcon || props.dropdown" class="spr-lozenge__prefix-icon spr-flex spr-h-3 spr-w-3 spr-items-center spr-overflow-hidden">
|
|
22
|
+
<slot name="postfixIcon">
|
|
23
|
+
<icon v-if="props.postfixIcon" :icon="props.postfixIcon" />
|
|
24
|
+
<icon v-else icon="ph:caret-down-fill" />
|
|
25
|
+
</slot>
|
|
26
|
+
</div>
|
|
18
27
|
</div>
|
|
19
28
|
</div>
|
|
20
|
-
<div v-if="visible && loading" :class="lozengeClasses.baseClasses" />
|
|
29
|
+
<div v-if="visible && loading" :class="['spr-lozenge__loading', lozengeClasses.baseClasses]" />
|
|
21
30
|
</div>
|
|
22
31
|
</template>
|
|
23
32
|
|
|
24
33
|
<script lang="ts" setup>
|
|
25
34
|
import { lozengePropTypes } from './lozenge';
|
|
26
35
|
import { useLozenge } from './use-lozenge';
|
|
36
|
+
import { Icon } from '@iconify/vue';
|
|
27
37
|
|
|
28
38
|
const props = defineProps(lozengePropTypes);
|
|
29
|
-
|
|
30
39
|
const { lozengeClasses } = useLozenge(props);
|
|
31
40
|
</script>
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { toRefs, computed, ComputedRef } from 'vue';
|
|
2
|
-
|
|
1
|
+
import { toRefs, computed, ComputedRef, useSlots } from 'vue';
|
|
3
2
|
import classNames from 'classnames';
|
|
4
|
-
|
|
5
3
|
import type { LozengePropTypes } from './lozenge';
|
|
6
4
|
|
|
7
5
|
interface LozengeClasses {
|
|
@@ -11,7 +9,9 @@ interface LozengeClasses {
|
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
export const useLozenge = (props: LozengePropTypes) => {
|
|
14
|
-
const { tone, fill, loading } = toRefs(props);
|
|
12
|
+
const { tone, fill, loading, interactive, url, dropdown } = toRefs(props);
|
|
13
|
+
const slots = useSlots();
|
|
14
|
+
const isInteractive = computed(() => interactive.value || dropdown.value);
|
|
15
15
|
|
|
16
16
|
const lozengeClasses: ComputedRef<LozengeClasses> = computed(() => {
|
|
17
17
|
const wrapperClasses = classNames({
|
|
@@ -25,31 +25,62 @@ export const useLozenge = (props: LozengePropTypes) => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
const toneClasses = classNames(
|
|
28
|
-
'spr-
|
|
28
|
+
'spr-box-border spr-h-[20px] spr-inline-flex spr-items-center spr-gap-size-spacing-6xs spr-rounded-md spr-border-solid spr-p-size-spacing-5xs spr-text-xs spr-uppercase',
|
|
29
29
|
{
|
|
30
|
-
'spr-
|
|
31
|
-
|
|
32
|
-
'spr-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
'spr-text-
|
|
37
|
-
'spr-
|
|
38
|
-
|
|
39
|
-
'spr-text-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
'spr-h-[20px]': !url.value,
|
|
31
|
+
'spr-h-[24px]': url.value || slots.avatar,
|
|
32
|
+
'spr-border': !fill.value,
|
|
33
|
+
'spr-cursor-pointer': isInteractive.value,
|
|
34
|
+
// #region - Styles for hollow lozenge
|
|
35
|
+
// Pending
|
|
36
|
+
'spr-text-mango-800 spr-background-color-pending-weak spr-border-mango-800': tone.value === 'pending' && !fill.value,
|
|
37
|
+
'hover:spr-bg-[#FFF89E] active:spr-bg-[#FFF56B]': tone.value === 'pending' && !fill.value && isInteractive.value,
|
|
38
|
+
// Information
|
|
39
|
+
'spr-text-blueberry-800 spr-background-color-information-weak spr-border-blueberry-800': tone.value === 'information' && !fill.value,
|
|
40
|
+
'hover:spr-bg-[#ADD6FF] active:spr-bg-[#7ABDFF]': tone.value === 'information' && !fill.value && isInteractive.value,
|
|
41
|
+
// Success
|
|
42
|
+
'spr-text-kangkong-800 spr-background-color-success-weak spr-border-kangkong-800': tone.value === 'success' && !fill.value,
|
|
43
|
+
'hover:spr-bg-[#AFF8C6] active:spr-bg-[#80F4A4]': tone.value === 'success' && !fill.value && isInteractive.value,
|
|
44
|
+
// Neutral
|
|
45
|
+
'spr-text-mushroom-800 spr-background-color-base spr-border-mushroom-800': tone.value === 'neutral' && !fill.value,
|
|
46
|
+
'hover:spr-bg-[#D3D9D9] active:spr-bg-[#B8C1C1]': tone.value === 'neutral' && !fill.value && isInteractive.value,
|
|
47
|
+
// Danger
|
|
48
|
+
'spr-text-tomato-800 spr-background-color-danger-weak spr-border-tomato-800': tone.value === 'danger' && !fill.value,
|
|
49
|
+
'hover:spr-bg-[#FCB0B3] active:spr-bg-[#FB7F83]': tone.value === 'danger' && !fill.value && isInteractive.value,
|
|
50
|
+
// Caution
|
|
51
|
+
'spr-text-carrot-800 spr-background-color-caution-weak spr-border-carrot-800': tone.value === 'caution' && !fill.value,
|
|
52
|
+
'hover:spr-bg-[#FFE79E] active:spr-bg-[#FFDA6B]': tone.value === 'caution' && !fill.value && isInteractive.value,
|
|
53
|
+
// Plain
|
|
54
|
+
'spr-text-color-strong spr-border-color-base spr-background-color': tone.value === 'plain' && !fill.value,
|
|
55
|
+
'hover:spr-bg-[#E6E6E6] active:spr-bg-[#CCCCCC]': tone.value === 'plain' && !fill.value && isInteractive.value,
|
|
56
|
+
// #endregion - Styles for hollow (!fill) lozenge
|
|
42
57
|
|
|
43
|
-
|
|
44
|
-
'spr-
|
|
45
|
-
|
|
46
|
-
'spr-
|
|
47
|
-
|
|
48
|
-
'spr-background-color-base
|
|
49
|
-
'spr-background-color-
|
|
50
|
-
|
|
51
|
-
'spr-background-color-
|
|
52
|
-
'spr-
|
|
58
|
+
// #region - Styles for filled lozenge
|
|
59
|
+
'spr-border-0': fill.value,
|
|
60
|
+
'spr-text-color-strong': fill.value && (tone.value === 'pending' || tone.value === 'neutral' || tone.value === 'caution' || tone.value === 'plain'),
|
|
61
|
+
'spr-text-color-inverted-strong': fill.value && (tone.value === 'information' || tone.value === 'success' || tone.value === 'danger'),
|
|
62
|
+
// Pending
|
|
63
|
+
'spr-background-color-pending-base': tone.value === 'pending' && fill.value,
|
|
64
|
+
'hover:spr-background-color-pending-hover active:spr-background-color-pending-pressed': tone.value === 'pending' && fill.value && isInteractive.value,
|
|
65
|
+
// Information
|
|
66
|
+
'spr-background-color-information-base': tone.value === 'information' && fill.value,
|
|
67
|
+
'hover:spr-background-color-information-hover active:spr-background-color-information-pressed': tone.value === 'information' && fill.value && isInteractive.value,
|
|
68
|
+
// Success
|
|
69
|
+
'spr-background-color-success-base': tone.value === 'success' && fill.value,
|
|
70
|
+
'hover:spr-background-color-success-hover active:spr-background-color-success-pressed': tone.value === 'success' && fill.value && isInteractive.value,
|
|
71
|
+
// Neutral
|
|
72
|
+
'spr-background-color-base': tone.value === 'neutral' && fill.value,
|
|
73
|
+
'hover:spr-background-color-surface active:spr-background-color-pressed': tone.value === 'neutral' && fill.value && isInteractive.value,
|
|
74
|
+
// Danger
|
|
75
|
+
'spr-background-color-danger-base': tone.value === 'danger' && fill.value,
|
|
76
|
+
'hover:spr-background-color-danger-hover active:spr-background-color-danger-pressed': tone.value === 'danger' && fill.value && isInteractive.value,
|
|
77
|
+
// Caution
|
|
78
|
+
'spr-background-color-caution-base': tone.value === 'caution' && fill.value,
|
|
79
|
+
'hover:spr-background-color-caution-hover active:spr-background-color-caution-pressed': tone.value === 'caution' && fill.value && isInteractive.value,
|
|
80
|
+
// Plain
|
|
81
|
+
'spr-background-color': tone.value === 'plain' && fill.value,
|
|
82
|
+
'hover:spr-background-color-hover active:spr-background-color-pressed': tone.value === 'plain' && fill.value && isInteractive.value,
|
|
83
|
+
// #endregion - Styles for filled lozenge
|
|
53
84
|
},
|
|
54
85
|
);
|
|
55
86
|
|