@dialpad/dialtone 9.61.0 → 9.64.0
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/css/dialtone-default-theme.css +129 -20
- package/dist/css/dialtone-default-theme.min.css +1 -1
- package/dist/css/dialtone.css +117 -20
- package/dist/css/dialtone.min.css +1 -1
- package/dist/css/tokens/tokens-dp-dark.css +12 -0
- package/dist/css/tokens/tokens-dp-light.css +12 -0
- package/dist/css/tokens/tokens-expressive-dark.css +12 -0
- package/dist/css/tokens/tokens-expressive-light.css +12 -0
- package/dist/css/tokens/tokens-expressive-sm-dark.css +12 -0
- package/dist/css/tokens/tokens-expressive-sm-light.css +12 -0
- package/dist/css/tokens/tokens-tmo-dark.css +12 -0
- package/dist/css/tokens/tokens-tmo-light.css +12 -0
- package/dist/themes/dp-dark.cjs +1 -1
- package/dist/themes/dp-dark.js +1 -1
- package/dist/themes/dp-light.cjs +1 -1
- package/dist/themes/dp-light.js +1 -1
- package/dist/themes/expressive-dark.cjs +1 -1
- package/dist/themes/expressive-dark.js +1 -1
- package/dist/themes/expressive-light.cjs +1 -1
- package/dist/themes/expressive-light.js +1 -1
- package/dist/themes/expressive-sm-dark.cjs +1 -1
- package/dist/themes/expressive-sm-dark.js +1 -1
- package/dist/themes/expressive-sm-light.cjs +1 -1
- package/dist/themes/expressive-sm-light.js +1 -1
- package/dist/themes/tmo-dark.cjs +1 -1
- package/dist/themes/tmo-dark.js +1 -1
- package/dist/themes/tmo-light.cjs +1 -1
- package/dist/themes/tmo-light.js +1 -1
- package/dist/tokens/css/tokens-dp-dark.css +12 -0
- package/dist/tokens/css/tokens-dp-light.css +12 -0
- package/dist/tokens/css/tokens-expressive-dark.css +12 -0
- package/dist/tokens/css/tokens-expressive-light.css +12 -0
- package/dist/tokens/css/tokens-expressive-sm-dark.css +12 -0
- package/dist/tokens/css/tokens-expressive-sm-light.css +12 -0
- package/dist/tokens/css/tokens-tmo-dark.css +12 -0
- package/dist/tokens/css/tokens-tmo-light.css +12 -0
- package/dist/tokens/doc.json +14168 -13816
- package/dist/tokens/less/tokens-dp-dark.less +2 -0
- package/dist/tokens/less/tokens-dp-light.less +2 -0
- package/dist/tokens/less/tokens-expressive-dark.less +2 -0
- package/dist/tokens/less/tokens-expressive-light.less +2 -0
- package/dist/tokens/less/tokens-expressive-sm-dark.less +2 -0
- package/dist/tokens/less/tokens-expressive-sm-light.less +2 -0
- package/dist/tokens/less/tokens-tmo-dark.less +2 -0
- package/dist/tokens/less/tokens-tmo-light.less +2 -0
- package/dist/tokens/tokens-dp-dark.json +2 -0
- package/dist/tokens/tokens-dp-light.json +2 -0
- package/dist/tokens/tokens-expressive-dark.json +2 -0
- package/dist/tokens/tokens-expressive-light.json +2 -0
- package/dist/tokens/tokens-expressive-sm-dark.json +2 -0
- package/dist/tokens/tokens-expressive-sm-light.json +2 -0
- package/dist/tokens/tokens-tmo-dark.json +2 -0
- package/dist/tokens/tokens-tmo-light.json +2 -0
- package/dist/vue2/component-documentation.json +1 -1
- package/dist/vue2/dialtone-vue.cjs +4 -0
- package/dist/vue2/dialtone-vue.cjs.map +1 -1
- package/dist/vue2/dialtone-vue.js +5 -1
- package/dist/vue2/dialtone-vue.js.map +1 -1
- package/dist/vue2/lib/avatar.cjs +4 -1
- package/dist/vue2/lib/avatar.cjs.map +1 -1
- package/dist/vue2/lib/avatar.js +4 -1
- package/dist/vue2/lib/avatar.js.map +1 -1
- package/dist/vue2/lib/button.cjs +2 -8
- package/dist/vue2/lib/button.cjs.map +1 -1
- package/dist/vue2/lib/button.js +2 -8
- package/dist/vue2/lib/button.js.map +1 -1
- package/dist/vue2/lib/combobox-multi-select.cjs +21 -3
- package/dist/vue2/lib/combobox-multi-select.cjs.map +1 -1
- package/dist/vue2/lib/combobox-multi-select.js +21 -3
- package/dist/vue2/lib/combobox-multi-select.js.map +1 -1
- package/dist/vue2/lib/general-row.cjs +2 -2
- package/dist/vue2/lib/general-row.cjs.map +1 -1
- package/dist/vue2/lib/general-row.js +2 -2
- package/dist/vue2/lib/general-row.js.map +1 -1
- package/dist/vue2/lib/keyboard-shortcut.cjs +1 -1
- package/dist/vue2/lib/keyboard-shortcut.cjs.map +1 -1
- package/dist/vue2/lib/keyboard-shortcut.js +1 -1
- package/dist/vue2/lib/keyboard-shortcut.js.map +1 -1
- package/dist/vue2/lib/message-input.cjs +1 -1
- package/dist/vue2/lib/message-input.cjs.map +1 -1
- package/dist/vue2/lib/message-input.js +1 -1
- package/dist/vue2/lib/message-input.js.map +1 -1
- package/dist/vue2/lib/split-button.cjs +512 -0
- package/dist/vue2/lib/split-button.cjs.map +1 -0
- package/dist/vue2/lib/split-button.js +512 -0
- package/dist/vue2/lib/split-button.js.map +1 -0
- package/dist/vue2/style.css +99 -93
- package/dist/vue2/types/components/avatar/avatar_constants.d.ts +2 -0
- package/dist/vue2/types/components/avatar/avatar_constants.d.ts.map +1 -1
- package/dist/vue2/types/components/avatar/index.d.ts +1 -1
- package/dist/vue2/types/components/button/button.vue.d.ts +2 -14
- package/dist/vue2/types/components/button/button.vue.d.ts.map +1 -1
- package/dist/vue2/types/components/split_button/index.d.ts +3 -0
- package/dist/vue2/types/components/split_button/index.d.ts.map +1 -0
- package/dist/vue2/types/components/split_button/split_button-alpha.vue.d.ts +183 -0
- package/dist/vue2/types/components/split_button/split_button-alpha.vue.d.ts.map +1 -0
- package/dist/vue2/types/components/split_button/split_button-omega.vue.d.ts +136 -0
- package/dist/vue2/types/components/split_button/split_button-omega.vue.d.ts.map +1 -0
- package/dist/vue2/types/components/split_button/split_button.vue.d.ts +347 -0
- package/dist/vue2/types/components/split_button/split_button.vue.d.ts.map +1 -0
- package/dist/vue2/types/components/split_button/split_button_constants.d.ts +12 -0
- package/dist/vue2/types/components/split_button/split_button_constants.d.ts.map +1 -0
- package/dist/vue2/types/index.d.ts +1 -0
- package/dist/vue2/types/recipes/comboboxes/combobox_multi_select/combobox_multi_select.vue.d.ts +1 -1
- package/dist/vue2/types/recipes/leftbar/general_row/general_row.vue.d.ts +1 -1
- package/dist/vue3/component-documentation.json +1 -1
- package/dist/vue3/dialtone-vue.cjs +4 -0
- package/dist/vue3/dialtone-vue.cjs.map +1 -1
- package/dist/vue3/dialtone-vue.js +5 -1
- package/dist/vue3/dialtone-vue.js.map +1 -1
- package/dist/vue3/lib/avatar.cjs +4 -1
- package/dist/vue3/lib/avatar.cjs.map +1 -1
- package/dist/vue3/lib/avatar.js +4 -1
- package/dist/vue3/lib/avatar.js.map +1 -1
- package/dist/vue3/lib/button.cjs +3 -9
- package/dist/vue3/lib/button.cjs.map +1 -1
- package/dist/vue3/lib/button.js +3 -9
- package/dist/vue3/lib/button.js.map +1 -1
- package/dist/vue3/lib/combobox-multi-select.cjs +24 -4
- package/dist/vue3/lib/combobox-multi-select.cjs.map +1 -1
- package/dist/vue3/lib/combobox-multi-select.js +24 -4
- package/dist/vue3/lib/combobox-multi-select.js.map +1 -1
- package/dist/vue3/lib/general-row.cjs +3 -3
- package/dist/vue3/lib/general-row.cjs.map +1 -1
- package/dist/vue3/lib/general-row.js +3 -3
- package/dist/vue3/lib/general-row.js.map +1 -1
- package/dist/vue3/lib/keyboard-shortcut.cjs +1 -1
- package/dist/vue3/lib/keyboard-shortcut.cjs.map +1 -1
- package/dist/vue3/lib/keyboard-shortcut.js +1 -1
- package/dist/vue3/lib/keyboard-shortcut.js.map +1 -1
- package/dist/vue3/lib/message-input.cjs +6 -2
- package/dist/vue3/lib/message-input.cjs.map +1 -1
- package/dist/vue3/lib/message-input.js +6 -2
- package/dist/vue3/lib/message-input.js.map +1 -1
- package/dist/vue3/lib/split-button.cjs +544 -0
- package/dist/vue3/lib/split-button.cjs.map +1 -0
- package/dist/vue3/lib/split-button.js +544 -0
- package/dist/vue3/lib/split-button.js.map +1 -0
- package/dist/vue3/style.css +99 -93
- package/dist/vue3/types/components/avatar/avatar_constants.d.ts +2 -0
- package/dist/vue3/types/components/avatar/avatar_constants.d.ts.map +1 -1
- package/dist/vue3/types/components/avatar/index.d.ts +1 -1
- package/dist/vue3/types/components/button/button.vue.d.ts +4 -16
- package/dist/vue3/types/components/button/button.vue.d.ts.map +1 -1
- package/dist/vue3/types/components/split_button/index.d.ts +3 -0
- package/dist/vue3/types/components/split_button/index.d.ts.map +1 -0
- package/dist/vue3/types/components/split_button/split_button-alpha.vue.d.ts +183 -0
- package/dist/vue3/types/components/split_button/split_button-alpha.vue.d.ts.map +1 -0
- package/dist/vue3/types/components/split_button/split_button-omega.vue.d.ts +136 -0
- package/dist/vue3/types/components/split_button/split_button-omega.vue.d.ts.map +1 -0
- package/dist/vue3/types/components/split_button/split_button.vue.d.ts +348 -0
- package/dist/vue3/types/components/split_button/split_button.vue.d.ts.map +1 -0
- package/dist/vue3/types/components/split_button/split_button_constants.d.ts +12 -0
- package/dist/vue3/types/components/split_button/split_button_constants.d.ts.map +1 -0
- package/dist/vue3/types/index.d.ts +1 -0
- package/dist/vue3/types/recipes/leftbar/general_row/general_row.vue.d.ts +1 -1
- package/package.json +3 -3
|
@@ -59,6 +59,7 @@ const lib_richTextEditor = require("./lib/rich-text-editor.cjs");
|
|
|
59
59
|
const lib_rootLayout = require("./lib/root-layout.cjs");
|
|
60
60
|
const lib_selectMenu = require("./lib/select-menu.cjs");
|
|
61
61
|
const lib_skeleton = require("./lib/skeleton.cjs");
|
|
62
|
+
const lib_splitButton = require("./lib/split-button.cjs");
|
|
62
63
|
const lib_stack = require("./lib/stack.cjs");
|
|
63
64
|
const stack_constants = require("./chunks/stack_constants-SMzMWnAQ.js");
|
|
64
65
|
const tab = require("./chunks/tab-FcsV5VmK.js");
|
|
@@ -190,6 +191,7 @@ exports.AVATAR_ICON_SIZES = lib_avatar.AVATAR_ICON_SIZES;
|
|
|
190
191
|
exports.AVATAR_KIND_MODIFIERS = lib_avatar.AVATAR_KIND_MODIFIERS;
|
|
191
192
|
exports.AVATAR_PRESENCE_SIZE_MODIFIERS = lib_avatar.AVATAR_PRESENCE_SIZE_MODIFIERS;
|
|
192
193
|
exports.AVATAR_PRESENCE_STATES = lib_avatar.AVATAR_PRESENCE_STATES;
|
|
194
|
+
exports.AVATAR_RANDOM_COLORS = lib_avatar.AVATAR_RANDOM_COLORS;
|
|
193
195
|
exports.AVATAR_SIZE_MODIFIERS = lib_avatar.AVATAR_SIZE_MODIFIERS;
|
|
194
196
|
exports.DtAvatar = lib_avatar.DtAvatar;
|
|
195
197
|
exports.BADGE_DECORATION_MODIFIERS = lib_badge.BADGE_DECORATION_MODIFIERS;
|
|
@@ -317,6 +319,8 @@ exports.SKELETON_RIPPLE_DURATION = lib_skeleton.SKELETON_RIPPLE_DURATION;
|
|
|
317
319
|
exports.SKELETON_SHAPES = lib_skeleton.SKELETON_SHAPES;
|
|
318
320
|
exports.SKELETON_SHAPE_SIZES = lib_skeleton.SKELETON_SHAPE_SIZES;
|
|
319
321
|
exports.SKELETON_TEXT_TYPES = lib_skeleton.SKELETON_TEXT_TYPES;
|
|
322
|
+
exports.DtSplitButton = lib_splitButton.DtSplitButton;
|
|
323
|
+
exports.SPLIT_BUTTON_ICON_SIZES = lib_splitButton.SPLIT_BUTTON_ICON_SIZES;
|
|
320
324
|
exports.DtStack = lib_stack.DtStack;
|
|
321
325
|
exports.DT_STACK_DIRECTION = stack_constants.DT_STACK_DIRECTION;
|
|
322
326
|
exports.DT_STACK_GAP = stack_constants.DT_STACK_GAP;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialtone-vue.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dialtone-vue.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -6,7 +6,7 @@ import { codeToEmojiData, customEmojiAssetUrl, defaultEmojiAssetUrl, emojiFileEx
|
|
|
6
6
|
import { CheckableMixin, GroupableMixin, InputMixin } from "./chunks/input-6kbd8Pju.js";
|
|
7
7
|
import { InputGroupMixin } from "./chunks/input_group-qVZaS5Bb.js";
|
|
8
8
|
import { KeyboardNavigation } from "./chunks/keyboard_list_navigation-ScXhrxya.js";
|
|
9
|
-
import { AVATAR_COLORS, AVATAR_GROUP_VALIDATOR, AVATAR_ICON_SIZES, AVATAR_KIND_MODIFIERS, AVATAR_PRESENCE_SIZE_MODIFIERS, AVATAR_PRESENCE_STATES, AVATAR_SIZE_MODIFIERS, DtAvatar } from "./lib/avatar.js";
|
|
9
|
+
import { AVATAR_COLORS, AVATAR_GROUP_VALIDATOR, AVATAR_ICON_SIZES, AVATAR_KIND_MODIFIERS, AVATAR_PRESENCE_SIZE_MODIFIERS, AVATAR_PRESENCE_STATES, AVATAR_RANDOM_COLORS, AVATAR_SIZE_MODIFIERS, DtAvatar } from "./lib/avatar.js";
|
|
10
10
|
import { BADGE_DECORATION_MODIFIERS, BADGE_KIND_MODIFIERS, BADGE_TYPE_MODIFIERS, DtBadge } from "./lib/badge.js";
|
|
11
11
|
import { DtBanner } from "./lib/banner.js";
|
|
12
12
|
import { BREADCRUMBS_INVERTED_MODIFIER, BREADCRUMB_ITEM_SELECTED_MODIFIER, DtBreadcrumbItem, DtBreadcrumbs } from "./lib/breadcrumbs.js";
|
|
@@ -57,6 +57,7 @@ import { DtRichTextEditor, RICH_TEXT_EDITOR_AUTOFOCUS_TYPES, RICH_TEXT_EDITOR_OU
|
|
|
57
57
|
import { DtRootLayout, ROOT_LAYOUT_RESPONSIVE_BREAKPOINTS, ROOT_LAYOUT_SIDEBAR_POSITIONS } from "./lib/root-layout.js";
|
|
58
58
|
import { DtSelectMenu, SELECT_SIZE_MODIFIERS, SELECT_STATE_MODIFIERS } from "./lib/select-menu.js";
|
|
59
59
|
import { DtSkeleton, DtSkeletonListItem, DtSkeletonParagraph, DtSkeletonShape, DtSkeletonText, SKELETON_HEADING_HEIGHTS, SKELETON_RIPPLE_DURATION, SKELETON_SHAPES, SKELETON_SHAPE_SIZES, SKELETON_TEXT_TYPES } from "./lib/skeleton.js";
|
|
60
|
+
import { DtSplitButton, SPLIT_BUTTON_ICON_SIZES } from "./lib/split-button.js";
|
|
60
61
|
import { DtStack } from "./lib/stack.js";
|
|
61
62
|
import { DT_STACK_DIRECTION, DT_STACK_GAP, DT_STACK_RESPONSIVE_BREAKPOINTS } from "./chunks/stack_constants-HraCekPm.js";
|
|
62
63
|
import { DtTab, DtTabGroup, TAB_IMPORTANCE_MODIFIERS, TAB_LIST_IMPORTANCE_MODIFIERS, TAB_LIST_KIND_MODIFIERS, TAB_LIST_SIZES } from "./chunks/tab-V4cb44Ry.js";
|
|
@@ -134,6 +135,7 @@ export {
|
|
|
134
135
|
AVATAR_KIND_MODIFIERS,
|
|
135
136
|
AVATAR_PRESENCE_SIZE_MODIFIERS,
|
|
136
137
|
AVATAR_PRESENCE_STATES,
|
|
138
|
+
AVATAR_RANDOM_COLORS,
|
|
137
139
|
AVATAR_SIZE_MODIFIERS,
|
|
138
140
|
BADGE_DECORATION_MODIFIERS,
|
|
139
141
|
BADGE_KIND_MODIFIERS,
|
|
@@ -244,6 +246,7 @@ export {
|
|
|
244
246
|
DtSkeletonParagraph,
|
|
245
247
|
DtSkeletonShape,
|
|
246
248
|
DtSkeletonText,
|
|
249
|
+
DtSplitButton,
|
|
247
250
|
DtStack,
|
|
248
251
|
DtTab,
|
|
249
252
|
DtTabGroup,
|
|
@@ -319,6 +322,7 @@ export {
|
|
|
319
322
|
SKELETON_SHAPES,
|
|
320
323
|
SKELETON_SHAPE_SIZES,
|
|
321
324
|
SKELETON_TEXT_TYPES,
|
|
325
|
+
SPLIT_BUTTON_ICON_SIZES,
|
|
322
326
|
TAB_IMPORTANCE_MODIFIERS,
|
|
323
327
|
TAB_LIST_IMPORTANCE_MODIFIERS,
|
|
324
328
|
TAB_LIST_KIND_MODIFIERS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialtone-vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dialtone-vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/vue2/lib/avatar.cjs
CHANGED
|
@@ -40,6 +40,7 @@ const AVATAR_ICON_SIZES = {
|
|
|
40
40
|
xl: "600"
|
|
41
41
|
};
|
|
42
42
|
const AVATAR_COLORS = [
|
|
43
|
+
"000",
|
|
43
44
|
"100",
|
|
44
45
|
"200",
|
|
45
46
|
"300",
|
|
@@ -59,6 +60,7 @@ const AVATAR_COLORS = [
|
|
|
59
60
|
"1700",
|
|
60
61
|
"1800"
|
|
61
62
|
];
|
|
63
|
+
const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);
|
|
62
64
|
const AVATAR_GROUP_VALIDATOR = (group) => group > 1;
|
|
63
65
|
function getIconNames() {
|
|
64
66
|
return [void 0, ...iconNames];
|
|
@@ -344,7 +346,7 @@ const _sfc_main = {
|
|
|
344
346
|
}
|
|
345
347
|
},
|
|
346
348
|
getColor() {
|
|
347
|
-
return this.color ?? common_utils.getRandomElement(
|
|
349
|
+
return this.color ?? common_utils.getRandomElement(AVATAR_RANDOM_COLORS, this.seed);
|
|
348
350
|
},
|
|
349
351
|
_loadedImageEventHandler(el) {
|
|
350
352
|
this.imageLoadedSuccessfully = true;
|
|
@@ -395,6 +397,7 @@ exports.AVATAR_ICON_SIZES = AVATAR_ICON_SIZES;
|
|
|
395
397
|
exports.AVATAR_KIND_MODIFIERS = AVATAR_KIND_MODIFIERS;
|
|
396
398
|
exports.AVATAR_PRESENCE_SIZE_MODIFIERS = AVATAR_PRESENCE_SIZE_MODIFIERS;
|
|
397
399
|
exports.AVATAR_PRESENCE_STATES = AVATAR_PRESENCE_STATES;
|
|
400
|
+
exports.AVATAR_RANDOM_COLORS = AVATAR_RANDOM_COLORS;
|
|
398
401
|
exports.AVATAR_SIZE_MODIFIERS = AVATAR_SIZE_MODIFIERS;
|
|
399
402
|
exports.DtAvatar = DtAvatar;
|
|
400
403
|
//# sourceMappingURL=avatar.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.cjs","sources":["../../components/avatar/avatar_constants.js","../../common/storybook_utils.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","import iconNames from '@dialpad/dialtone-icons/icons.json';\nimport illustrationNames from '@dialpad/dialtone-icons/illustrations.json';\n\n/**\n * Will use a Vue SFC to render the template rather than a template string.\n * This is useful for more complex components that are hard to work with and\n * get messy when rendered via a template string. Will pass args and argTypes\n * into the component, so it is able to be live edited with storybook controls addon.\n * @param component this will get the component name\n * @param defaultTemplate we will mount in this component\n * @param argsData storybook control args\n * @returns {component} the template component with props and args added.\n */\n\nexport function createRenderConfig (component, defaultTemplate, argsData) {\n return {\n components: { [component.name]: defaultTemplate },\n props: [...Object.keys(component.props ?? {}), ...Object.keys(argsData)],\n setup (props) {\n return { props };\n },\n template: `<${component.name} v-bind=\"props\" />`,\n };\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIconNames () {\n return [undefined, ...iconNames];\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIllustrationNames () {\n return [undefined, ...illustrationNames];\n}\n\nexport const generateTemplate = (component,\n { props = [], excludeProps = [], customProps = [], childTemplate } = {}) => {\n if (!component) {\n console.warn('Generate template: Please provide a component');\n return '';\n }\n\n const { name, props: componentProps } = component;\n const finalProps = props.length ? props : Object.keys(componentProps);\n const normalizedName = name.split(/(?=[A-Z])/).join('-').toLowerCase();\n\n const startFragment = `<${normalizedName}`;\n\n const propFragments = finalProps\n .filter(prop => !excludeProps.includes(prop))\n .map(prop => `:${prop}=\"${prop}\"`);\n\n const endFragment = childTemplate ? `>${childTemplate}</${normalizedName}>` : ' />';\n\n return [startFragment, ...propFragments, ...customProps, endFragment].join(' ');\n};\n\nexport default {\n generateTemplate,\n getIconNames,\n getIllustrationNames,\n createRenderConfig,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <dt-icon\n v-else-if=\"iconName\"\n :name=\"iconName\"\n :aria-label=\"iconAriaLabel\"\n :size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n data-qa=\"dt-avatar-icon\"\n />\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"overlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <dt-icon\n v-if=\"overlayIcon\"\n class=\"d-avatar__overlay-icon\"\n :name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport { DtIcon } from '@/components/icon';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { getIconNames } from '@/common/storybook_utils.js';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\nconst ICONS_LIST = getIconNames();\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence, DtIcon },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The icon that overlays the avatar\n */\n overlayIcon: {\n type: String,\n default: '',\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon name to be displayed on the avatar\n */\n iconName: {\n type: String,\n default: undefined,\n validator: (name) => ICONS_LIST.includes(name),\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n };\n },\n\n computed: {\n isNotIconType () {\n return !this.iconName;\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: this.isNotIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":["DtPresence","DtIcon","getUniqueString","ICON_SIZE_MODIFIERS","getRandomElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"avatar.cjs","sources":["../../components/avatar/avatar_constants.js","../../common/storybook_utils.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '000',\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\n// We do not use the color '000' (grey) in the randomized avatar colors, but it can still be set manually.\nexport const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","import iconNames from '@dialpad/dialtone-icons/icons.json';\nimport illustrationNames from '@dialpad/dialtone-icons/illustrations.json';\n\n/**\n * Will use a Vue SFC to render the template rather than a template string.\n * This is useful for more complex components that are hard to work with and\n * get messy when rendered via a template string. Will pass args and argTypes\n * into the component, so it is able to be live edited with storybook controls addon.\n * @param component this will get the component name\n * @param defaultTemplate we will mount in this component\n * @param argsData storybook control args\n * @returns {component} the template component with props and args added.\n */\n\nexport function createRenderConfig (component, defaultTemplate, argsData) {\n return {\n components: { [component.name]: defaultTemplate },\n props: [...Object.keys(component.props ?? {}), ...Object.keys(argsData)],\n setup (props) {\n return { props };\n },\n template: `<${component.name} v-bind=\"props\" />`,\n };\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIconNames () {\n return [undefined, ...iconNames];\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIllustrationNames () {\n return [undefined, ...illustrationNames];\n}\n\nexport const generateTemplate = (component,\n { props = [], excludeProps = [], customProps = [], childTemplate } = {}) => {\n if (!component) {\n console.warn('Generate template: Please provide a component');\n return '';\n }\n\n const { name, props: componentProps } = component;\n const finalProps = props.length ? props : Object.keys(componentProps);\n const normalizedName = name.split(/(?=[A-Z])/).join('-').toLowerCase();\n\n const startFragment = `<${normalizedName}`;\n\n const propFragments = finalProps\n .filter(prop => !excludeProps.includes(prop))\n .map(prop => `:${prop}=\"${prop}\"`);\n\n const endFragment = childTemplate ? `>${childTemplate}</${normalizedName}>` : ' />';\n\n return [startFragment, ...propFragments, ...customProps, endFragment].join(' ');\n};\n\nexport default {\n generateTemplate,\n getIconNames,\n getIllustrationNames,\n createRenderConfig,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <dt-icon\n v-else-if=\"iconName\"\n :name=\"iconName\"\n :aria-label=\"iconAriaLabel\"\n :size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n data-qa=\"dt-avatar-icon\"\n />\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"overlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <dt-icon\n v-if=\"overlayIcon\"\n class=\"d-avatar__overlay-icon\"\n :name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport { DtIcon } from '@/components/icon';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { getIconNames } from '@/common/storybook_utils.js';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\nconst ICONS_LIST = getIconNames();\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence, DtIcon },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The icon that overlays the avatar\n */\n overlayIcon: {\n type: String,\n default: '',\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon name to be displayed on the avatar\n */\n iconName: {\n type: String,\n default: undefined,\n validator: (name) => ICONS_LIST.includes(name),\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n };\n },\n\n computed: {\n isNotIconType () {\n return !this.iconName;\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: this.isNotIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_RANDOM_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":["DtPresence","DtIcon","getUniqueString","ICON_SIZE_MODIFIERS","getRandomElement"],"mappings":"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"}
|
package/dist/vue2/lib/avatar.js
CHANGED
|
@@ -38,6 +38,7 @@ const AVATAR_ICON_SIZES = {
|
|
|
38
38
|
xl: "600"
|
|
39
39
|
};
|
|
40
40
|
const AVATAR_COLORS = [
|
|
41
|
+
"000",
|
|
41
42
|
"100",
|
|
42
43
|
"200",
|
|
43
44
|
"300",
|
|
@@ -57,6 +58,7 @@ const AVATAR_COLORS = [
|
|
|
57
58
|
"1700",
|
|
58
59
|
"1800"
|
|
59
60
|
];
|
|
61
|
+
const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);
|
|
60
62
|
const AVATAR_GROUP_VALIDATOR = (group) => group > 1;
|
|
61
63
|
function getIconNames() {
|
|
62
64
|
return [void 0, ...iconNames];
|
|
@@ -342,7 +344,7 @@ const _sfc_main = {
|
|
|
342
344
|
}
|
|
343
345
|
},
|
|
344
346
|
getColor() {
|
|
345
|
-
return this.color ?? getRandomElement(
|
|
347
|
+
return this.color ?? getRandomElement(AVATAR_RANDOM_COLORS, this.seed);
|
|
346
348
|
},
|
|
347
349
|
_loadedImageEventHandler(el) {
|
|
348
350
|
this.imageLoadedSuccessfully = true;
|
|
@@ -394,6 +396,7 @@ export {
|
|
|
394
396
|
AVATAR_KIND_MODIFIERS,
|
|
395
397
|
AVATAR_PRESENCE_SIZE_MODIFIERS,
|
|
396
398
|
AVATAR_PRESENCE_STATES,
|
|
399
|
+
AVATAR_RANDOM_COLORS,
|
|
397
400
|
AVATAR_SIZE_MODIFIERS,
|
|
398
401
|
DtAvatar
|
|
399
402
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.js","sources":["../../components/avatar/avatar_constants.js","../../common/storybook_utils.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","import iconNames from '@dialpad/dialtone-icons/icons.json';\nimport illustrationNames from '@dialpad/dialtone-icons/illustrations.json';\n\n/**\n * Will use a Vue SFC to render the template rather than a template string.\n * This is useful for more complex components that are hard to work with and\n * get messy when rendered via a template string. Will pass args and argTypes\n * into the component, so it is able to be live edited with storybook controls addon.\n * @param component this will get the component name\n * @param defaultTemplate we will mount in this component\n * @param argsData storybook control args\n * @returns {component} the template component with props and args added.\n */\n\nexport function createRenderConfig (component, defaultTemplate, argsData) {\n return {\n components: { [component.name]: defaultTemplate },\n props: [...Object.keys(component.props ?? {}), ...Object.keys(argsData)],\n setup (props) {\n return { props };\n },\n template: `<${component.name} v-bind=\"props\" />`,\n };\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIconNames () {\n return [undefined, ...iconNames];\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIllustrationNames () {\n return [undefined, ...illustrationNames];\n}\n\nexport const generateTemplate = (component,\n { props = [], excludeProps = [], customProps = [], childTemplate } = {}) => {\n if (!component) {\n console.warn('Generate template: Please provide a component');\n return '';\n }\n\n const { name, props: componentProps } = component;\n const finalProps = props.length ? props : Object.keys(componentProps);\n const normalizedName = name.split(/(?=[A-Z])/).join('-').toLowerCase();\n\n const startFragment = `<${normalizedName}`;\n\n const propFragments = finalProps\n .filter(prop => !excludeProps.includes(prop))\n .map(prop => `:${prop}=\"${prop}\"`);\n\n const endFragment = childTemplate ? `>${childTemplate}</${normalizedName}>` : ' />';\n\n return [startFragment, ...propFragments, ...customProps, endFragment].join(' ');\n};\n\nexport default {\n generateTemplate,\n getIconNames,\n getIllustrationNames,\n createRenderConfig,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <dt-icon\n v-else-if=\"iconName\"\n :name=\"iconName\"\n :aria-label=\"iconAriaLabel\"\n :size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n data-qa=\"dt-avatar-icon\"\n />\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"overlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <dt-icon\n v-if=\"overlayIcon\"\n class=\"d-avatar__overlay-icon\"\n :name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport { DtIcon } from '@/components/icon';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { getIconNames } from '@/common/storybook_utils.js';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\nconst ICONS_LIST = getIconNames();\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence, DtIcon },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The icon that overlays the avatar\n */\n overlayIcon: {\n type: String,\n default: '',\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon name to be displayed on the avatar\n */\n iconName: {\n type: String,\n default: undefined,\n validator: (name) => ICONS_LIST.includes(name),\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n };\n },\n\n computed: {\n isNotIconType () {\n return !this.iconName;\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: this.isNotIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"avatar.js","sources":["../../components/avatar/avatar_constants.js","../../common/storybook_utils.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '000',\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\n// We do not use the color '000' (grey) in the randomized avatar colors, but it can still be set manually.\nexport const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","import iconNames from '@dialpad/dialtone-icons/icons.json';\nimport illustrationNames from '@dialpad/dialtone-icons/illustrations.json';\n\n/**\n * Will use a Vue SFC to render the template rather than a template string.\n * This is useful for more complex components that are hard to work with and\n * get messy when rendered via a template string. Will pass args and argTypes\n * into the component, so it is able to be live edited with storybook controls addon.\n * @param component this will get the component name\n * @param defaultTemplate we will mount in this component\n * @param argsData storybook control args\n * @returns {component} the template component with props and args added.\n */\n\nexport function createRenderConfig (component, defaultTemplate, argsData) {\n return {\n components: { [component.name]: defaultTemplate },\n props: [...Object.keys(component.props ?? {}), ...Object.keys(argsData)],\n setup (props) {\n return { props };\n },\n template: `<${component.name} v-bind=\"props\" />`,\n };\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIconNames () {\n return [undefined, ...iconNames];\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIllustrationNames () {\n return [undefined, ...illustrationNames];\n}\n\nexport const generateTemplate = (component,\n { props = [], excludeProps = [], customProps = [], childTemplate } = {}) => {\n if (!component) {\n console.warn('Generate template: Please provide a component');\n return '';\n }\n\n const { name, props: componentProps } = component;\n const finalProps = props.length ? props : Object.keys(componentProps);\n const normalizedName = name.split(/(?=[A-Z])/).join('-').toLowerCase();\n\n const startFragment = `<${normalizedName}`;\n\n const propFragments = finalProps\n .filter(prop => !excludeProps.includes(prop))\n .map(prop => `:${prop}=\"${prop}\"`);\n\n const endFragment = childTemplate ? `>${childTemplate}</${normalizedName}>` : ' />';\n\n return [startFragment, ...propFragments, ...customProps, endFragment].join(' ');\n};\n\nexport default {\n generateTemplate,\n getIconNames,\n getIllustrationNames,\n createRenderConfig,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <dt-icon\n v-else-if=\"iconName\"\n :name=\"iconName\"\n :aria-label=\"iconAriaLabel\"\n :size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n data-qa=\"dt-avatar-icon\"\n />\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"overlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <dt-icon\n v-if=\"overlayIcon\"\n class=\"d-avatar__overlay-icon\"\n :name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport { DtIcon } from '@/components/icon';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { getIconNames } from '@/common/storybook_utils.js';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\nconst ICONS_LIST = getIconNames();\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence, DtIcon },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The icon that overlays the avatar\n */\n overlayIcon: {\n type: String,\n default: '',\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon name to be displayed on the avatar\n */\n iconName: {\n type: String,\n default: undefined,\n validator: (name) => ICONS_LIST.includes(name),\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n };\n },\n\n computed: {\n isNotIconType () {\n return !this.iconName;\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: this.isNotIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_RANDOM_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":[],"mappings":"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"}
|
package/dist/vue2/lib/button.cjs
CHANGED
|
@@ -123,13 +123,7 @@ const _sfc_main = {
|
|
|
123
123
|
},
|
|
124
124
|
/**
|
|
125
125
|
* HTML button disabled attribute
|
|
126
|
-
* <a
|
|
127
|
-
* class="d-link"
|
|
128
|
-
* href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled"
|
|
129
|
-
* target="_blank"
|
|
130
|
-
* >
|
|
131
|
-
* (Reference)
|
|
132
|
-
* </a>
|
|
126
|
+
* <a class="d-link" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled" target="_blank"> (Reference) </a>
|
|
133
127
|
* @values true, false
|
|
134
128
|
*/
|
|
135
129
|
disabled: {
|
|
@@ -315,7 +309,7 @@ const _sfc_main = {
|
|
|
315
309
|
return true;
|
|
316
310
|
},
|
|
317
311
|
shouldRenderIcon() {
|
|
318
|
-
return this.$scopedSlots.icon && !this.link;
|
|
312
|
+
return this.$scopedSlots.icon && this.$scopedSlots.icon() && !this.link;
|
|
319
313
|
},
|
|
320
314
|
isIconOnly() {
|
|
321
315
|
return this.shouldRenderIcon() && !this.$slots.default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.cjs","sources":["../../components/button/button_constants.js","../../components/button/button.vue"],"sourcesContent":["export const BUTTON_SIZE_MODIFIERS = {\n xs: 'd-btn--xs',\n sm: 'd-btn--sm',\n md: '',\n lg: 'd-btn--lg',\n xl: 'd-btn--xl',\n};\n\nexport const BUTTON_KIND_MODIFIERS = {\n default: '',\n muted: 'd-btn--muted',\n danger: 'd-btn--danger',\n inverted: 'd-btn--inverted',\n};\n\nexport const BUTTON_IMPORTANCE_MODIFIERS = {\n clear: '',\n primary: 'd-btn--primary',\n outlined: 'd-btn--outlined',\n};\n\nexport const BUTTON_TYPES = ['submit', 'reset', 'button'];\n\nexport const ICON_POSITION_MODIFIERS = {\n left: 'd-btn__icon--left',\n right: 'd-btn__icon--right',\n top: 'd-btn__icon--top',\n bottom: 'd-btn__icon--bottom',\n};\n\nexport const INVALID_COMBINATION = [\n {\n circle: true,\n kind: 'default',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'default', 'primary'),\n },\n {\n circle: true,\n kind: 'danger',\n importance: 'outlined',\n message: _invalidCombinationMessage(true, 'danger', 'outlined'),\n },\n {\n circle: true,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'muted', 'primary'),\n },\n {\n circle: false,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(false, 'muted', 'primary'),\n },\n];\n\nexport const BUTTON_ICON_SIZES = {\n xs: '200',\n sm: '200',\n md: '300',\n lg: '400',\n xl: '500',\n};\n\nfunction _invalidCombinationMessage (circle, kind, importance) {\n return `You cannot have a ${circle ? 'circle ' : ''}button \\\nwith kind: ${kind} and importance: ${importance} as it \\\ndoes not exist in our design system. \\\nSee https://dialtone.dialpad.com/components/button.html for a \\\nlist of available button styles`;\n}\n\nexport default {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n BUTTON_ICON_SIZES,\n};\n","<template>\n <button\n :class=\"[\n 'base-button__button',\n buttonClasses(),\n ]\"\n data-qa=\"dt-button\"\n :type=\"type\"\n :disabled=\"disabled\"\n :style=\"{ width: width }\"\n :aria-live=\"computedAriaLive\"\n :aria-label=\"loading ? 'loading' : $attrs['aria-label']\"\n v-on=\"buttonListeners\"\n >\n <!-- NOTE(cormac): This span is needed since we can't apply styles to slots. -->\n <span\n v-if=\"shouldRenderIcon()\"\n data-qa=\"dt-button-icon\"\n :class=\"[\n 'base-button__icon',\n 'd-btn__icon',\n ICON_POSITION_MODIFIERS[iconPosition],\n ]\"\n >\n <!-- @slot Button icon -->\n <slot\n name=\"icon\"\n :icon-size=\"iconSize\"\n />\n </span>\n <span\n v-if=\"$slots.default\"\n data-qa=\"dt-button-label\"\n :class=\"['d-btn__label', 'base-button__label', labelClass]\"\n >\n <!-- @slot Content within button -->\n <slot />\n </span>\n </button>\n</template>\n\n<script>\nimport Vue from 'vue';\n\nimport {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_ICON_SIZES,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n} from './button_constants';\n\nimport { LINK_KIND_MODIFIERS, getLinkKindModifier } from '@/components/link';\n\n/**\n * A button is a UI element which allows users to take an action throughout the app.\n * It is important a button is identifiable, consistent, and communicates its actions clearly,\n * and is appropriately sized to its action.\n * @see https://dialtone.dialpad.com/components/button.html\n */\nexport default {\n name: 'DtButton',\n\n props: {\n /**\n * Whether the button is a circle or not.\n * @values true, false\n */\n circle: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The position of the icon slot within the button.\n * @values left, right, top, bottom\n */\n iconPosition: {\n type: String,\n default: 'left',\n validator: (position) => Object.keys(ICON_POSITION_MODIFIERS).includes(position),\n },\n\n /**\n * The fill and outline of the button associated with its visual importance.\n * @values clear, outlined, primary\n */\n importance: {\n type: String,\n default: 'primary',\n validator: (i) => Object.keys(BUTTON_IMPORTANCE_MODIFIERS).includes(i),\n },\n\n /**\n * Whether the button should be styled as a link or not.\n * @values true, false\n * @see DtLink\n */\n link: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the link and button if the button is styled as a link.\n * @values default, warning, danger, success, muted\n * @see DtLink\n */\n linkKind: {\n type: String,\n default: 'default',\n validator: (lk) => Object.keys(LINK_KIND_MODIFIERS).includes(lk),\n },\n\n /**\n * Determines whether the link should have inverted styling if the button is styled as a link.\n * @values true, false\n * @see DtLink\n */\n linkInverted: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button disabled attribute\n * <a\n * class=\"d-link\"\n * href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled\"\n * target=\"_blank\"\n * >\n * (Reference)\n * </a>\n * @values true, false\n */\n disabled: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button type attribute\n * <a\n * class=\"d-link\"\n * href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type\"\n * target=\"_blank\"\n * >\n * (Reference)\n * </a>\n * @values button, submit, reset\n */\n type: {\n type: String,\n default: 'button',\n validator: (t) => BUTTON_TYPES.includes(t),\n },\n\n /**\n * Button width, accepts\n * <a class=\"d-link\" href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/width\" target=\"_blank\">\n * CSS width attribute\n * </a>\n * values\n */\n width: {\n type: String,\n default: null,\n },\n\n /**\n * The size of the button.\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (s) => Object.keys(BUTTON_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Used to customize the label container\n */\n labelClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Whether the button should display a loading animation or not.\n * @values true, false\n */\n loading: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the button.\n * @values default, muted, danger, inverted\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(BUTTON_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Determines whether a screenreader reads live updates of\n * the button content to the user while the button\n * is in focus. default is to not.\n * @values true, false\n */\n assertiveOnFocus: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Determines whether the button should have active styling\n * default is false.\n * @values true, false\n */\n active: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native button focus in event\n *\n * @event focusin\n * @type {FocusEvent}\n */\n 'focusin',\n\n /**\n * Native button focus out event\n *\n * @event focusout\n * @type {FocusEvent}\n */\n 'focusout',\n ],\n\n data () {\n return {\n ICON_POSITION_MODIFIERS,\n // whether the button is currently in focus\n isInFocus: false,\n };\n },\n\n computed: {\n\n buttonListeners () {\n if (!this.assertiveOnFocus) {\n return this.$listeners;\n }\n return {\n ...this.$listeners,\n focusin: (e) => {\n this.isInFocus = true;\n },\n\n focusout: (e) => {\n this.isInFocus = false;\n },\n };\n },\n\n computedAriaLive () {\n return this.assertiveOnFocus && this.isInFocus ? 'assertive' : this.$attrs.ariaLive;\n },\n\n iconSize () {\n return BUTTON_ICON_SIZES[this.size];\n },\n },\n\n watch: {\n $props: {\n deep: true,\n immediate: true,\n handler () {\n if (process.env.NODE_ENV === 'production') return;\n\n if (this.circle && this.link) {\n Vue.util.warn('You cannot enable circle and link at the same time', this);\n }\n\n this.isInvalidPropCombination(this.circle, this.kind, this.importance);\n },\n },\n },\n\n methods: {\n buttonClasses () {\n if (this.link) {\n return [\n 'd-link',\n getLinkKindModifier(this.linkKind, this.linkInverted),\n BUTTON_SIZE_MODIFIERS[this.size],\n ];\n }\n return [\n 'd-btn',\n BUTTON_IMPORTANCE_MODIFIERS[this.importance],\n BUTTON_KIND_MODIFIERS[this.kind],\n BUTTON_SIZE_MODIFIERS[this.size],\n {\n 'd-btn--circle': this.circle,\n 'd-btn--loading': this.loading,\n 'd-btn--icon-only': this.isIconOnly(),\n 'd-btn--vertical': this.isVerticalIconLayout(),\n 'd-btn--active': this.active,\n },\n ];\n },\n\n isInvalidPropCombination (circle, kind, importance) {\n for (const row of INVALID_COMBINATION) {\n if (circle === row.circle && kind === row.kind && importance === row.importance) {\n console.warn(row.message);\n return false;\n }\n }\n return true;\n },\n\n shouldRenderIcon () {\n return this.$scopedSlots.icon && !this.link;\n },\n\n isIconOnly () {\n return this.shouldRenderIcon() && !this.$slots.default;\n },\n\n isVerticalIconLayout () {\n return !this.isIconOnly() && ['top', 'bottom'].includes(this.iconPosition);\n },\n },\n};\n</script>\n"],"names":["LINK_KIND_MODIFIERS","getLinkKindModifier"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"button.cjs","sources":["../../components/button/button_constants.js","../../components/button/button.vue"],"sourcesContent":["export const BUTTON_SIZE_MODIFIERS = {\n xs: 'd-btn--xs',\n sm: 'd-btn--sm',\n md: '',\n lg: 'd-btn--lg',\n xl: 'd-btn--xl',\n};\n\nexport const BUTTON_KIND_MODIFIERS = {\n default: '',\n muted: 'd-btn--muted',\n danger: 'd-btn--danger',\n inverted: 'd-btn--inverted',\n};\n\nexport const BUTTON_IMPORTANCE_MODIFIERS = {\n clear: '',\n primary: 'd-btn--primary',\n outlined: 'd-btn--outlined',\n};\n\nexport const BUTTON_TYPES = ['submit', 'reset', 'button'];\n\nexport const ICON_POSITION_MODIFIERS = {\n left: 'd-btn__icon--left',\n right: 'd-btn__icon--right',\n top: 'd-btn__icon--top',\n bottom: 'd-btn__icon--bottom',\n};\n\nexport const INVALID_COMBINATION = [\n {\n circle: true,\n kind: 'default',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'default', 'primary'),\n },\n {\n circle: true,\n kind: 'danger',\n importance: 'outlined',\n message: _invalidCombinationMessage(true, 'danger', 'outlined'),\n },\n {\n circle: true,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'muted', 'primary'),\n },\n {\n circle: false,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(false, 'muted', 'primary'),\n },\n];\n\nexport const BUTTON_ICON_SIZES = {\n xs: '200',\n sm: '200',\n md: '300',\n lg: '400',\n xl: '500',\n};\n\nfunction _invalidCombinationMessage (circle, kind, importance) {\n return `You cannot have a ${circle ? 'circle ' : ''}button \\\nwith kind: ${kind} and importance: ${importance} as it \\\ndoes not exist in our design system. \\\nSee https://dialtone.dialpad.com/components/button.html for a \\\nlist of available button styles`;\n}\n\nexport default {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n BUTTON_ICON_SIZES,\n};\n","<template>\n <button\n :class=\"[\n 'base-button__button',\n buttonClasses(),\n ]\"\n data-qa=\"dt-button\"\n :type=\"type\"\n :disabled=\"disabled\"\n :style=\"{ width: width }\"\n :aria-live=\"computedAriaLive\"\n :aria-label=\"loading ? 'loading' : $attrs['aria-label']\"\n v-on=\"buttonListeners\"\n >\n <!-- NOTE(cormac): This span is needed since we can't apply styles to slots. -->\n <span\n v-if=\"shouldRenderIcon()\"\n data-qa=\"dt-button-icon\"\n :class=\"[\n 'base-button__icon',\n 'd-btn__icon',\n ICON_POSITION_MODIFIERS[iconPosition],\n ]\"\n >\n <!-- @slot Button icon -->\n <slot\n name=\"icon\"\n :icon-size=\"iconSize\"\n />\n </span>\n <span\n v-if=\"$slots.default\"\n data-qa=\"dt-button-label\"\n :class=\"['d-btn__label', 'base-button__label', labelClass]\"\n >\n <!-- @slot Content within button -->\n <slot />\n </span>\n </button>\n</template>\n\n<script>\nimport Vue from 'vue';\n\nimport {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_ICON_SIZES,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n} from './button_constants';\n\nimport { LINK_KIND_MODIFIERS, getLinkKindModifier } from '@/components/link';\n\n/**\n * A button is a UI element which allows users to take an action throughout the app.\n * It is important a button is identifiable, consistent, and communicates its actions clearly,\n * and is appropriately sized to its action.\n * @see https://dialtone.dialpad.com/components/button.html\n */\nexport default {\n name: 'DtButton',\n\n props: {\n /**\n * Whether the button is a circle or not.\n * @values true, false\n */\n circle: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The position of the icon slot within the button.\n * @values left, right, top, bottom\n */\n iconPosition: {\n type: String,\n default: 'left',\n validator: (position) => Object.keys(ICON_POSITION_MODIFIERS).includes(position),\n },\n\n /**\n * The fill and outline of the button associated with its visual importance.\n * @values clear, outlined, primary\n */\n importance: {\n type: String,\n default: 'primary',\n validator: (i) => Object.keys(BUTTON_IMPORTANCE_MODIFIERS).includes(i),\n },\n\n /**\n * Whether the button should be styled as a link or not.\n * @values true, false\n * @see DtLink\n */\n link: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the link and button if the button is styled as a link.\n * @values default, warning, danger, success, muted\n * @see DtLink\n */\n linkKind: {\n type: String,\n default: 'default',\n validator: (lk) => Object.keys(LINK_KIND_MODIFIERS).includes(lk),\n },\n\n /**\n * Determines whether the link should have inverted styling if the button is styled as a link.\n * @values true, false\n * @see DtLink\n */\n linkInverted: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button disabled attribute\n * <a class=\"d-link\" href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled\" target=\"_blank\"> (Reference) </a>\n * @values true, false\n */\n disabled: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button type attribute\n * <a\n * class=\"d-link\"\n * href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type\"\n * target=\"_blank\"\n * >\n * (Reference)\n * </a>\n * @values button, submit, reset\n */\n type: {\n type: String,\n default: 'button',\n validator: (t) => BUTTON_TYPES.includes(t),\n },\n\n /**\n * Button width, accepts\n * <a class=\"d-link\" href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/width\" target=\"_blank\">\n * CSS width attribute\n * </a>\n * values\n */\n width: {\n type: String,\n default: null,\n },\n\n /**\n * The size of the button.\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (s) => Object.keys(BUTTON_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Used to customize the label container\n */\n labelClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Whether the button should display a loading animation or not.\n * @values true, false\n */\n loading: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the button.\n * @values default, muted, danger, inverted\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(BUTTON_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Determines whether a screenreader reads live updates of\n * the button content to the user while the button\n * is in focus. default is to not.\n * @values true, false\n */\n assertiveOnFocus: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Determines whether the button should have active styling\n * default is false.\n * @values true, false\n */\n active: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native button focus in event\n *\n * @event focusin\n * @type {FocusEvent}\n */\n 'focusin',\n\n /**\n * Native button focus out event\n *\n * @event focusout\n * @type {FocusEvent}\n */\n 'focusout',\n ],\n\n data () {\n return {\n ICON_POSITION_MODIFIERS,\n // whether the button is currently in focus\n isInFocus: false,\n };\n },\n\n computed: {\n\n buttonListeners () {\n if (!this.assertiveOnFocus) {\n return this.$listeners;\n }\n return {\n ...this.$listeners,\n focusin: (e) => {\n this.isInFocus = true;\n },\n\n focusout: (e) => {\n this.isInFocus = false;\n },\n };\n },\n\n computedAriaLive () {\n return this.assertiveOnFocus && this.isInFocus ? 'assertive' : this.$attrs.ariaLive;\n },\n\n iconSize () {\n return BUTTON_ICON_SIZES[this.size];\n },\n },\n\n watch: {\n $props: {\n deep: true,\n immediate: true,\n handler () {\n if (process.env.NODE_ENV === 'production') return;\n\n if (this.circle && this.link) {\n Vue.util.warn('You cannot enable circle and link at the same time', this);\n }\n\n this.isInvalidPropCombination(this.circle, this.kind, this.importance);\n },\n },\n },\n\n methods: {\n buttonClasses () {\n if (this.link) {\n return [\n 'd-link',\n getLinkKindModifier(this.linkKind, this.linkInverted),\n BUTTON_SIZE_MODIFIERS[this.size],\n ];\n }\n return [\n 'd-btn',\n BUTTON_IMPORTANCE_MODIFIERS[this.importance],\n BUTTON_KIND_MODIFIERS[this.kind],\n BUTTON_SIZE_MODIFIERS[this.size],\n {\n 'd-btn--circle': this.circle,\n 'd-btn--loading': this.loading,\n 'd-btn--icon-only': this.isIconOnly(),\n 'd-btn--vertical': this.isVerticalIconLayout(),\n 'd-btn--active': this.active,\n },\n ];\n },\n\n isInvalidPropCombination (circle, kind, importance) {\n for (const row of INVALID_COMBINATION) {\n if (circle === row.circle && kind === row.kind && importance === row.importance) {\n console.warn(row.message);\n return false;\n }\n }\n return true;\n },\n\n shouldRenderIcon () {\n return this.$scopedSlots.icon && this.$scopedSlots.icon() && !this.link;\n },\n\n isIconOnly () {\n return this.shouldRenderIcon() && !this.$slots.default;\n },\n\n isVerticalIconLayout () {\n return !this.isIconOnly() && ['top', 'bottom'].includes(this.iconPosition);\n },\n },\n};\n</script>\n"],"names":["LINK_KIND_MODIFIERS","getLinkKindModifier"],"mappings":"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"}
|
package/dist/vue2/lib/button.js
CHANGED
|
@@ -121,13 +121,7 @@ const _sfc_main = {
|
|
|
121
121
|
},
|
|
122
122
|
/**
|
|
123
123
|
* HTML button disabled attribute
|
|
124
|
-
* <a
|
|
125
|
-
* class="d-link"
|
|
126
|
-
* href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled"
|
|
127
|
-
* target="_blank"
|
|
128
|
-
* >
|
|
129
|
-
* (Reference)
|
|
130
|
-
* </a>
|
|
124
|
+
* <a class="d-link" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled" target="_blank"> (Reference) </a>
|
|
131
125
|
* @values true, false
|
|
132
126
|
*/
|
|
133
127
|
disabled: {
|
|
@@ -313,7 +307,7 @@ const _sfc_main = {
|
|
|
313
307
|
return true;
|
|
314
308
|
},
|
|
315
309
|
shouldRenderIcon() {
|
|
316
|
-
return this.$scopedSlots.icon && !this.link;
|
|
310
|
+
return this.$scopedSlots.icon && this.$scopedSlots.icon() && !this.link;
|
|
317
311
|
},
|
|
318
312
|
isIconOnly() {
|
|
319
313
|
return this.shouldRenderIcon() && !this.$slots.default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sources":["../../components/button/button_constants.js","../../components/button/button.vue"],"sourcesContent":["export const BUTTON_SIZE_MODIFIERS = {\n xs: 'd-btn--xs',\n sm: 'd-btn--sm',\n md: '',\n lg: 'd-btn--lg',\n xl: 'd-btn--xl',\n};\n\nexport const BUTTON_KIND_MODIFIERS = {\n default: '',\n muted: 'd-btn--muted',\n danger: 'd-btn--danger',\n inverted: 'd-btn--inverted',\n};\n\nexport const BUTTON_IMPORTANCE_MODIFIERS = {\n clear: '',\n primary: 'd-btn--primary',\n outlined: 'd-btn--outlined',\n};\n\nexport const BUTTON_TYPES = ['submit', 'reset', 'button'];\n\nexport const ICON_POSITION_MODIFIERS = {\n left: 'd-btn__icon--left',\n right: 'd-btn__icon--right',\n top: 'd-btn__icon--top',\n bottom: 'd-btn__icon--bottom',\n};\n\nexport const INVALID_COMBINATION = [\n {\n circle: true,\n kind: 'default',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'default', 'primary'),\n },\n {\n circle: true,\n kind: 'danger',\n importance: 'outlined',\n message: _invalidCombinationMessage(true, 'danger', 'outlined'),\n },\n {\n circle: true,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'muted', 'primary'),\n },\n {\n circle: false,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(false, 'muted', 'primary'),\n },\n];\n\nexport const BUTTON_ICON_SIZES = {\n xs: '200',\n sm: '200',\n md: '300',\n lg: '400',\n xl: '500',\n};\n\nfunction _invalidCombinationMessage (circle, kind, importance) {\n return `You cannot have a ${circle ? 'circle ' : ''}button \\\nwith kind: ${kind} and importance: ${importance} as it \\\ndoes not exist in our design system. \\\nSee https://dialtone.dialpad.com/components/button.html for a \\\nlist of available button styles`;\n}\n\nexport default {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n BUTTON_ICON_SIZES,\n};\n","<template>\n <button\n :class=\"[\n 'base-button__button',\n buttonClasses(),\n ]\"\n data-qa=\"dt-button\"\n :type=\"type\"\n :disabled=\"disabled\"\n :style=\"{ width: width }\"\n :aria-live=\"computedAriaLive\"\n :aria-label=\"loading ? 'loading' : $attrs['aria-label']\"\n v-on=\"buttonListeners\"\n >\n <!-- NOTE(cormac): This span is needed since we can't apply styles to slots. -->\n <span\n v-if=\"shouldRenderIcon()\"\n data-qa=\"dt-button-icon\"\n :class=\"[\n 'base-button__icon',\n 'd-btn__icon',\n ICON_POSITION_MODIFIERS[iconPosition],\n ]\"\n >\n <!-- @slot Button icon -->\n <slot\n name=\"icon\"\n :icon-size=\"iconSize\"\n />\n </span>\n <span\n v-if=\"$slots.default\"\n data-qa=\"dt-button-label\"\n :class=\"['d-btn__label', 'base-button__label', labelClass]\"\n >\n <!-- @slot Content within button -->\n <slot />\n </span>\n </button>\n</template>\n\n<script>\nimport Vue from 'vue';\n\nimport {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_ICON_SIZES,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n} from './button_constants';\n\nimport { LINK_KIND_MODIFIERS, getLinkKindModifier } from '@/components/link';\n\n/**\n * A button is a UI element which allows users to take an action throughout the app.\n * It is important a button is identifiable, consistent, and communicates its actions clearly,\n * and is appropriately sized to its action.\n * @see https://dialtone.dialpad.com/components/button.html\n */\nexport default {\n name: 'DtButton',\n\n props: {\n /**\n * Whether the button is a circle or not.\n * @values true, false\n */\n circle: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The position of the icon slot within the button.\n * @values left, right, top, bottom\n */\n iconPosition: {\n type: String,\n default: 'left',\n validator: (position) => Object.keys(ICON_POSITION_MODIFIERS).includes(position),\n },\n\n /**\n * The fill and outline of the button associated with its visual importance.\n * @values clear, outlined, primary\n */\n importance: {\n type: String,\n default: 'primary',\n validator: (i) => Object.keys(BUTTON_IMPORTANCE_MODIFIERS).includes(i),\n },\n\n /**\n * Whether the button should be styled as a link or not.\n * @values true, false\n * @see DtLink\n */\n link: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the link and button if the button is styled as a link.\n * @values default, warning, danger, success, muted\n * @see DtLink\n */\n linkKind: {\n type: String,\n default: 'default',\n validator: (lk) => Object.keys(LINK_KIND_MODIFIERS).includes(lk),\n },\n\n /**\n * Determines whether the link should have inverted styling if the button is styled as a link.\n * @values true, false\n * @see DtLink\n */\n linkInverted: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button disabled attribute\n * <a\n * class=\"d-link\"\n * href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled\"\n * target=\"_blank\"\n * >\n * (Reference)\n * </a>\n * @values true, false\n */\n disabled: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button type attribute\n * <a\n * class=\"d-link\"\n * href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type\"\n * target=\"_blank\"\n * >\n * (Reference)\n * </a>\n * @values button, submit, reset\n */\n type: {\n type: String,\n default: 'button',\n validator: (t) => BUTTON_TYPES.includes(t),\n },\n\n /**\n * Button width, accepts\n * <a class=\"d-link\" href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/width\" target=\"_blank\">\n * CSS width attribute\n * </a>\n * values\n */\n width: {\n type: String,\n default: null,\n },\n\n /**\n * The size of the button.\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (s) => Object.keys(BUTTON_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Used to customize the label container\n */\n labelClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Whether the button should display a loading animation or not.\n * @values true, false\n */\n loading: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the button.\n * @values default, muted, danger, inverted\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(BUTTON_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Determines whether a screenreader reads live updates of\n * the button content to the user while the button\n * is in focus. default is to not.\n * @values true, false\n */\n assertiveOnFocus: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Determines whether the button should have active styling\n * default is false.\n * @values true, false\n */\n active: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native button focus in event\n *\n * @event focusin\n * @type {FocusEvent}\n */\n 'focusin',\n\n /**\n * Native button focus out event\n *\n * @event focusout\n * @type {FocusEvent}\n */\n 'focusout',\n ],\n\n data () {\n return {\n ICON_POSITION_MODIFIERS,\n // whether the button is currently in focus\n isInFocus: false,\n };\n },\n\n computed: {\n\n buttonListeners () {\n if (!this.assertiveOnFocus) {\n return this.$listeners;\n }\n return {\n ...this.$listeners,\n focusin: (e) => {\n this.isInFocus = true;\n },\n\n focusout: (e) => {\n this.isInFocus = false;\n },\n };\n },\n\n computedAriaLive () {\n return this.assertiveOnFocus && this.isInFocus ? 'assertive' : this.$attrs.ariaLive;\n },\n\n iconSize () {\n return BUTTON_ICON_SIZES[this.size];\n },\n },\n\n watch: {\n $props: {\n deep: true,\n immediate: true,\n handler () {\n if (process.env.NODE_ENV === 'production') return;\n\n if (this.circle && this.link) {\n Vue.util.warn('You cannot enable circle and link at the same time', this);\n }\n\n this.isInvalidPropCombination(this.circle, this.kind, this.importance);\n },\n },\n },\n\n methods: {\n buttonClasses () {\n if (this.link) {\n return [\n 'd-link',\n getLinkKindModifier(this.linkKind, this.linkInverted),\n BUTTON_SIZE_MODIFIERS[this.size],\n ];\n }\n return [\n 'd-btn',\n BUTTON_IMPORTANCE_MODIFIERS[this.importance],\n BUTTON_KIND_MODIFIERS[this.kind],\n BUTTON_SIZE_MODIFIERS[this.size],\n {\n 'd-btn--circle': this.circle,\n 'd-btn--loading': this.loading,\n 'd-btn--icon-only': this.isIconOnly(),\n 'd-btn--vertical': this.isVerticalIconLayout(),\n 'd-btn--active': this.active,\n },\n ];\n },\n\n isInvalidPropCombination (circle, kind, importance) {\n for (const row of INVALID_COMBINATION) {\n if (circle === row.circle && kind === row.kind && importance === row.importance) {\n console.warn(row.message);\n return false;\n }\n }\n return true;\n },\n\n shouldRenderIcon () {\n return this.$scopedSlots.icon && !this.link;\n },\n\n isIconOnly () {\n return this.shouldRenderIcon() && !this.$slots.default;\n },\n\n isVerticalIconLayout () {\n return !this.isIconOnly() && ['top', 'bottom'].includes(this.iconPosition);\n },\n },\n};\n</script>\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"button.js","sources":["../../components/button/button_constants.js","../../components/button/button.vue"],"sourcesContent":["export const BUTTON_SIZE_MODIFIERS = {\n xs: 'd-btn--xs',\n sm: 'd-btn--sm',\n md: '',\n lg: 'd-btn--lg',\n xl: 'd-btn--xl',\n};\n\nexport const BUTTON_KIND_MODIFIERS = {\n default: '',\n muted: 'd-btn--muted',\n danger: 'd-btn--danger',\n inverted: 'd-btn--inverted',\n};\n\nexport const BUTTON_IMPORTANCE_MODIFIERS = {\n clear: '',\n primary: 'd-btn--primary',\n outlined: 'd-btn--outlined',\n};\n\nexport const BUTTON_TYPES = ['submit', 'reset', 'button'];\n\nexport const ICON_POSITION_MODIFIERS = {\n left: 'd-btn__icon--left',\n right: 'd-btn__icon--right',\n top: 'd-btn__icon--top',\n bottom: 'd-btn__icon--bottom',\n};\n\nexport const INVALID_COMBINATION = [\n {\n circle: true,\n kind: 'default',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'default', 'primary'),\n },\n {\n circle: true,\n kind: 'danger',\n importance: 'outlined',\n message: _invalidCombinationMessage(true, 'danger', 'outlined'),\n },\n {\n circle: true,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(true, 'muted', 'primary'),\n },\n {\n circle: false,\n kind: 'muted',\n importance: 'primary',\n message: _invalidCombinationMessage(false, 'muted', 'primary'),\n },\n];\n\nexport const BUTTON_ICON_SIZES = {\n xs: '200',\n sm: '200',\n md: '300',\n lg: '400',\n xl: '500',\n};\n\nfunction _invalidCombinationMessage (circle, kind, importance) {\n return `You cannot have a ${circle ? 'circle ' : ''}button \\\nwith kind: ${kind} and importance: ${importance} as it \\\ndoes not exist in our design system. \\\nSee https://dialtone.dialpad.com/components/button.html for a \\\nlist of available button styles`;\n}\n\nexport default {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n BUTTON_ICON_SIZES,\n};\n","<template>\n <button\n :class=\"[\n 'base-button__button',\n buttonClasses(),\n ]\"\n data-qa=\"dt-button\"\n :type=\"type\"\n :disabled=\"disabled\"\n :style=\"{ width: width }\"\n :aria-live=\"computedAriaLive\"\n :aria-label=\"loading ? 'loading' : $attrs['aria-label']\"\n v-on=\"buttonListeners\"\n >\n <!-- NOTE(cormac): This span is needed since we can't apply styles to slots. -->\n <span\n v-if=\"shouldRenderIcon()\"\n data-qa=\"dt-button-icon\"\n :class=\"[\n 'base-button__icon',\n 'd-btn__icon',\n ICON_POSITION_MODIFIERS[iconPosition],\n ]\"\n >\n <!-- @slot Button icon -->\n <slot\n name=\"icon\"\n :icon-size=\"iconSize\"\n />\n </span>\n <span\n v-if=\"$slots.default\"\n data-qa=\"dt-button-label\"\n :class=\"['d-btn__label', 'base-button__label', labelClass]\"\n >\n <!-- @slot Content within button -->\n <slot />\n </span>\n </button>\n</template>\n\n<script>\nimport Vue from 'vue';\n\nimport {\n BUTTON_SIZE_MODIFIERS,\n BUTTON_KIND_MODIFIERS,\n BUTTON_IMPORTANCE_MODIFIERS,\n BUTTON_ICON_SIZES,\n BUTTON_TYPES,\n ICON_POSITION_MODIFIERS,\n INVALID_COMBINATION,\n} from './button_constants';\n\nimport { LINK_KIND_MODIFIERS, getLinkKindModifier } from '@/components/link';\n\n/**\n * A button is a UI element which allows users to take an action throughout the app.\n * It is important a button is identifiable, consistent, and communicates its actions clearly,\n * and is appropriately sized to its action.\n * @see https://dialtone.dialpad.com/components/button.html\n */\nexport default {\n name: 'DtButton',\n\n props: {\n /**\n * Whether the button is a circle or not.\n * @values true, false\n */\n circle: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The position of the icon slot within the button.\n * @values left, right, top, bottom\n */\n iconPosition: {\n type: String,\n default: 'left',\n validator: (position) => Object.keys(ICON_POSITION_MODIFIERS).includes(position),\n },\n\n /**\n * The fill and outline of the button associated with its visual importance.\n * @values clear, outlined, primary\n */\n importance: {\n type: String,\n default: 'primary',\n validator: (i) => Object.keys(BUTTON_IMPORTANCE_MODIFIERS).includes(i),\n },\n\n /**\n * Whether the button should be styled as a link or not.\n * @values true, false\n * @see DtLink\n */\n link: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the link and button if the button is styled as a link.\n * @values default, warning, danger, success, muted\n * @see DtLink\n */\n linkKind: {\n type: String,\n default: 'default',\n validator: (lk) => Object.keys(LINK_KIND_MODIFIERS).includes(lk),\n },\n\n /**\n * Determines whether the link should have inverted styling if the button is styled as a link.\n * @values true, false\n * @see DtLink\n */\n linkInverted: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button disabled attribute\n * <a class=\"d-link\" href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled\" target=\"_blank\"> (Reference) </a>\n * @values true, false\n */\n disabled: {\n type: Boolean,\n default: false,\n },\n\n /**\n * HTML button type attribute\n * <a\n * class=\"d-link\"\n * href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type\"\n * target=\"_blank\"\n * >\n * (Reference)\n * </a>\n * @values button, submit, reset\n */\n type: {\n type: String,\n default: 'button',\n validator: (t) => BUTTON_TYPES.includes(t),\n },\n\n /**\n * Button width, accepts\n * <a class=\"d-link\" href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/width\" target=\"_blank\">\n * CSS width attribute\n * </a>\n * values\n */\n width: {\n type: String,\n default: null,\n },\n\n /**\n * The size of the button.\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (s) => Object.keys(BUTTON_SIZE_MODIFIERS).includes(s),\n },\n\n /**\n * Used to customize the label container\n */\n labelClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Whether the button should display a loading animation or not.\n * @values true, false\n */\n loading: {\n type: Boolean,\n default: false,\n },\n\n /**\n * The color of the button.\n * @values default, muted, danger, inverted\n */\n kind: {\n type: String,\n default: 'default',\n validator: (k) => Object.keys(BUTTON_KIND_MODIFIERS).includes(k),\n },\n\n /**\n * Determines whether a screenreader reads live updates of\n * the button content to the user while the button\n * is in focus. default is to not.\n * @values true, false\n */\n assertiveOnFocus: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Determines whether the button should have active styling\n * default is false.\n * @values true, false\n */\n active: {\n type: Boolean,\n default: false,\n },\n },\n\n emits: [\n /**\n * Native button click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n\n /**\n * Native button focus in event\n *\n * @event focusin\n * @type {FocusEvent}\n */\n 'focusin',\n\n /**\n * Native button focus out event\n *\n * @event focusout\n * @type {FocusEvent}\n */\n 'focusout',\n ],\n\n data () {\n return {\n ICON_POSITION_MODIFIERS,\n // whether the button is currently in focus\n isInFocus: false,\n };\n },\n\n computed: {\n\n buttonListeners () {\n if (!this.assertiveOnFocus) {\n return this.$listeners;\n }\n return {\n ...this.$listeners,\n focusin: (e) => {\n this.isInFocus = true;\n },\n\n focusout: (e) => {\n this.isInFocus = false;\n },\n };\n },\n\n computedAriaLive () {\n return this.assertiveOnFocus && this.isInFocus ? 'assertive' : this.$attrs.ariaLive;\n },\n\n iconSize () {\n return BUTTON_ICON_SIZES[this.size];\n },\n },\n\n watch: {\n $props: {\n deep: true,\n immediate: true,\n handler () {\n if (process.env.NODE_ENV === 'production') return;\n\n if (this.circle && this.link) {\n Vue.util.warn('You cannot enable circle and link at the same time', this);\n }\n\n this.isInvalidPropCombination(this.circle, this.kind, this.importance);\n },\n },\n },\n\n methods: {\n buttonClasses () {\n if (this.link) {\n return [\n 'd-link',\n getLinkKindModifier(this.linkKind, this.linkInverted),\n BUTTON_SIZE_MODIFIERS[this.size],\n ];\n }\n return [\n 'd-btn',\n BUTTON_IMPORTANCE_MODIFIERS[this.importance],\n BUTTON_KIND_MODIFIERS[this.kind],\n BUTTON_SIZE_MODIFIERS[this.size],\n {\n 'd-btn--circle': this.circle,\n 'd-btn--loading': this.loading,\n 'd-btn--icon-only': this.isIconOnly(),\n 'd-btn--vertical': this.isVerticalIconLayout(),\n 'd-btn--active': this.active,\n },\n ];\n },\n\n isInvalidPropCombination (circle, kind, importance) {\n for (const row of INVALID_COMBINATION) {\n if (circle === row.circle && kind === row.kind && importance === row.importance) {\n console.warn(row.message);\n return false;\n }\n }\n return true;\n },\n\n shouldRenderIcon () {\n return this.$scopedSlots.icon && this.$scopedSlots.icon() && !this.link;\n },\n\n isIconOnly () {\n return this.shouldRenderIcon() && !this.$slots.default;\n },\n\n isVerticalIconLayout () {\n return !this.isIconOnly() && ['top', 'bottom'].includes(this.iconPosition);\n },\n },\n};\n</script>\n"],"names":[],"mappings":"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"}
|