tide-design-system 2.0.37 → 2.0.39

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/index.html ADDED
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>TIDE Sandbox</title>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
7
+ <meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=1.0, initial-scale=1.0 user-scalable=no"/>
8
+ <script src="src/contexts/sandbox/app-sandbox.ts" type="module"></script>
9
+ </head>
10
+
11
+ <body>
12
+ <div id="app-sandbox" />
13
+ </body>
14
+ </html>
package/index.ts CHANGED
@@ -33,6 +33,7 @@ import TideToggle from '@/components/TideToggle.vue';
33
33
  import type { Alert } from '@/types/Alert';
34
34
  import type { Badge, BadgePremium, BadgeTrustedYears } from '@/types/Badge';
35
35
  import type { BreadCrumb } from '@/types/BreadCrumb';
36
+ import type { Breakpoint, Media } from '@/types/Breakpoint';
36
37
  import type { Detail } from '@/types/Detail';
37
38
  import type { Element, ElementTextAsIcon } from '@/types/Element';
38
39
  import type { FacetComponentIdRange, RangeData } from '@/types/FacetRange';
@@ -70,7 +71,7 @@ import type { Realm } from '@/types/Realm';
70
71
  import type { RealmConfig } from '@/types/RealmConfig';
71
72
  import type { SelectOption, SelectOptionGroup } from '@/types/Select';
72
73
  import type { Size } from '@/types/Size';
73
- import type { Breakpoint, CssUtility } from '@/types/Styles';
74
+ import type { CssUtility } from '@/types/Styles';
74
75
  import type { Tab } from '@/types/Tab';
75
76
  import type { Target } from '@/types/Target';
76
77
  import type { TextInputType } from '@/types/TextInput';
@@ -78,7 +79,8 @@ import type { ValidationError, ValidationResult, ValidationLength, Validator } f
78
79
 
79
80
  import { ALERT } from '@/types/Alert';
80
81
  import { BADGE, BADGE_PREMIUM, BADGE_TRUSTED } from '@/types/Badge';
81
- import { BREAKPOINT, CSS } from '@/types/Styles';
82
+ import { BREAKPOINT, MEDIA } from '@/types/Breakpoint';
83
+ import { CSS } from '@/types/Styles';
82
84
  import { ELEMENT, ELEMENT_TEXT_AS_ICON } from '@/types/Element';
83
85
  import { FORMAT, FORMAT_REGEX } from '@/types/Formatted';
84
86
  import { ICON } from '@/types/Icon';
@@ -120,6 +122,7 @@ export type {
120
122
  Input,
121
123
  Link,
122
124
  ListingMedia,
125
+ Media,
123
126
  MediaSlideType,
124
127
  Orientation,
125
128
  Priority,
@@ -162,6 +165,7 @@ export {
162
165
  FORMAT,
163
166
  FORMAT_REGEX,
164
167
  ICON,
168
+ MEDIA,
165
169
  MEDIA_SLIDE_TYPES,
166
170
  ORIENTATION,
167
171
  PRIORITY,
package/package.json CHANGED
@@ -54,5 +54,5 @@
54
54
  "main": "dist/tide-design-system.cjs",
55
55
  "module": "dist/tide-design-system.esm.js",
56
56
  "types": "dist/tide-design-system.esm.d.ts",
57
- "version": "2.0.37"
57
+ "version": "2.0.39"
58
58
  }
@@ -1,3 +1,4 @@
1
+ @import './reset.css';
1
2
  @import './variables.css';
2
3
  @import './utilities.css';
3
4
  @import './dynamic-buttons.css';
@@ -1,15 +1,20 @@
1
1
  <script lang="ts" setup>
2
+ import type { Source } from '@/types/Source';
3
+
4
+ import TideImage from '@/components/TideImage.vue';
2
5
  import { CSS } from '@/types/Styles';
3
6
 
4
7
  type Props = {
5
8
  alt: string;
6
9
  isLazy: boolean;
10
+ sources?: Source[];
7
11
  src: string;
8
12
  };
9
13
 
10
- withDefaults(defineProps<Props>(), {
14
+ const props = withDefaults(defineProps<Props>(), {
11
15
  alt: '',
12
16
  isLazy: true,
17
+ sources: () => [],
13
18
  });
14
19
  </script>
15
20
 
@@ -25,12 +30,12 @@
25
30
  CSS.AXIS2.CENTER,
26
31
  ]"
27
32
  >
28
- <img
29
- :alt="alt"
30
- :class="['tide-background-image', CSS.OBJECT.COVER, CSS.WIDTH.FULL, CSS.HEIGHT.FULL]"
31
- :fetchpriority="isLazy ? undefined : 'high'"
32
- :loading="isLazy ? 'lazy' : undefined"
33
- :src="src"
33
+ <TideImage
34
+ :class="['tide-background-image', CSS.WIDTH.FULL, CSS.HEIGHT.FULL]"
35
+ :is-lazy="props.isLazy"
36
+ :sources="props.sources"
37
+ :src="props.src"
38
+ alt="props.alt"
34
39
  />
35
40
  </div>
36
41
 
@@ -42,4 +47,10 @@
42
47
  .tide-background-image {
43
48
  z-index: -1;
44
49
  }
50
+
51
+ :deep(.tide-background-image img) {
52
+ width: 100%;
53
+ height: 100%;
54
+ object-fit: cover;
55
+ }
45
56
  </style>
@@ -1,40 +1,59 @@
1
1
  <script lang="ts" setup>
2
2
  import { ref } from 'vue';
3
3
 
4
+ import type { Source } from '@/types/Source';
5
+
4
6
  import { CSS } from '@/types/Styles';
5
7
 
6
8
  type Props = {
7
- alt?: string;
9
+ alt: string;
8
10
  isLazy?: boolean;
9
- src?: string;
11
+ sources?: Source[];
12
+ src: string;
10
13
  };
11
14
 
12
15
  const props = withDefaults(defineProps<Props>(), {
13
16
  alt: '',
14
17
  isLazy: true,
15
- src: undefined,
18
+ sources: () => [],
16
19
  });
17
20
 
18
21
  const tideImage = ref();
19
-
20
22
  const imageDefault = 'https://cdn-static-rec.tilabs.io/image-coming-soon-512.png';
21
23
 
22
24
  const setImageFromDefault = () => {
23
- tideImage.value.src = imageDefault;
25
+ const src = tideImage.value.currentSrc;
26
+ const currentSource = tideImage.value.parentElement.querySelector(`source[srcset="${src}"]`);
27
+
28
+ if (currentSource) {
29
+ currentSource.srcset = imageDefault;
30
+ } else {
31
+ tideImage.value.src = imageDefault;
32
+ }
24
33
  };
25
34
 
26
35
  defineExpose(tideImage.value);
27
36
  </script>
28
37
 
29
38
  <template>
30
- <img
31
- :alt="alt"
32
- :class="['tide-image', CSS.OBJECT.CENTER, CSS.OBJECT.COVER]"
33
- :loading="props.isLazy ? 'lazy' : 'eager'"
34
- ref="tideImage"
35
- :src="src ?? imageDefault"
36
- @error="setImageFromDefault"
37
- />
39
+ <picture :class="['tide-image']">
40
+ <source
41
+ :key="source.srcset"
42
+ :media="`(min-width:${source.media}px)`"
43
+ :srcset="source.srcset"
44
+ v-for="source in props.sources"
45
+ />
46
+
47
+ <img
48
+ :alt="alt"
49
+ :class="[CSS.OBJECT.CENTER, CSS.OBJECT.COVER]"
50
+ :fetchpriority="isLazy ? undefined : 'high'"
51
+ :loading="props.isLazy ? 'lazy' : 'eager'"
52
+ ref="tideImage"
53
+ :src="src ?? imageDefault"
54
+ @error="setImageFromDefault"
55
+ />
56
+ </picture>
38
57
  </template>
39
58
 
40
59
  <style scoped></style>
@@ -0,0 +1,5 @@
1
+ <script lang="ts" setup></script>
2
+
3
+ <template>
4
+ <div />
5
+ </template>
@@ -0,0 +1,10 @@
1
+ import { createApp } from 'vue';
2
+
3
+ import AppSandbox from './AppSandbox.vue';
4
+
5
+ import '@/assets/css/main.css';
6
+
7
+ const app = createApp(AppSandbox);
8
+ const appIdSelector = '#app-sandbox';
9
+
10
+ app.mount(appIdSelector);
@@ -1,5 +1,33 @@
1
- import { parameters, argTypeBooleanUnrequired } from '@/utilities/storybook';
1
+ import type { StoryContext } from '@storybook/vue3';
2
+
3
+ import type { Source } from '@/types/Source';
4
+
2
5
  import TideBackgroundImage from '@/components/TideBackgroundImage.vue';
6
+ import { MEDIA } from '@/types/Breakpoint';
7
+ import { argTypeBooleanUnrequired } from '@/utilities/storybook';
8
+
9
+ const formatSnippet = (_code: string, context: StoryContext) => {
10
+ const { args } = context;
11
+ const argsWithValues: string[] = [`alt="${args.alt}"`];
12
+ const hasSources = args.sources !== null;
13
+ const hasSourcesLength = hasSources ? (args.sources as any).length > 0 : false;
14
+
15
+ if (args.isLazy !== undefined) argsWithValues.push(`:is-lazy="${args.isLazy}"`);
16
+ if (hasSources && hasSourcesLength) argsWithValues.push(`:sources="sources"`);
17
+ if (args.src) argsWithValues.push(`:src="${args.src}"`);
18
+
19
+ return `<TideBackgroundImage ${argsWithValues.join(' ')} />`;
20
+ };
21
+
22
+ const parameters = {
23
+ docs: {
24
+ source: {
25
+ format: 'vue',
26
+ language: 'html',
27
+ transform: formatSnippet,
28
+ },
29
+ },
30
+ };
3
31
 
4
32
  const render = (args: any) => ({
5
33
  components: { TideBackgroundImage },
@@ -15,23 +43,55 @@ const render = (args: any) => ({
15
43
  `,
16
44
  });
17
45
 
46
+ const sources: Source[] = [
47
+ {
48
+ media: MEDIA.XL,
49
+ srcset: 'https://placedog.net/1919/400',
50
+ },
51
+ {
52
+ media: MEDIA.LG,
53
+ srcset: 'https://placedog.net/1231/400',
54
+ },
55
+ {
56
+ media: MEDIA.MD,
57
+ srcset: 'https://placedog.net/991/400',
58
+ },
59
+ {
60
+ media: MEDIA.SM,
61
+ srcset: 'https://placedog.net/767/400',
62
+ },
63
+ ];
64
+
18
65
  export default {
19
66
  argTypes: {
20
67
  alt: {
21
68
  control: 'text',
22
- description: 'Button text',
69
+ description: `Text display when image can't be loaded.`,
23
70
  table: {
24
71
  defaultValue: { summary: 'None' },
25
72
  type: { summary: 'string' },
26
73
  },
27
74
  },
75
+ default: {
76
+ table: {
77
+ disable: true,
78
+ },
79
+ },
28
80
  isLazy: {
29
81
  ...argTypeBooleanUnrequired,
30
- description: 'Determines if the image should be lazy-loaded',
82
+ description: `Determines whether to delay loading until image is in viewport.`,
83
+ },
84
+ sources: {
85
+ control: 'object',
86
+ description: `Determines image sources by breakpoint.`,
87
+ table: {
88
+ defaultValue: { summary: 'None' },
89
+ type: { summary: 'Source[]' },
90
+ },
31
91
  },
32
92
  src: {
33
93
  control: 'text',
34
- description: 'Source URL for the background image',
94
+ description: `Image URL.`,
35
95
  table: {
36
96
  defaultValue: { summary: 'None' },
37
97
  type: { summary: 'string' },
@@ -40,8 +100,9 @@ export default {
40
100
  },
41
101
  args: {
42
102
  alt: '',
43
- isLazy: true,
44
- src: 'https://placedog.net/500/400',
103
+ isLazy: undefined,
104
+ sources,
105
+ src: 'https://placedog.net/375/400',
45
106
  },
46
107
  component: TideBackgroundImage,
47
108
  parameters,
@@ -1,5 +1,52 @@
1
+ import type { StoryContext } from '@storybook/vue3';
2
+
3
+ import type { Source } from '@/types/Source';
4
+
1
5
  import TideImage from '@/components/TideImage.vue';
2
- import { argTypeBooleanUnrequired, parameters } from '@/utilities/storybook';
6
+ import { MEDIA } from '@/types/Breakpoint';
7
+ import { argTypeBooleanUnrequired } from '@/utilities/storybook';
8
+
9
+ const sources: Source[] = [
10
+ {
11
+ media: MEDIA.XL,
12
+ srcset: 'https://placedog.net/1919/400',
13
+ },
14
+ {
15
+ media: MEDIA.LG,
16
+ srcset: 'https://placedog.net/1231/400',
17
+ },
18
+ {
19
+ media: MEDIA.MD,
20
+ srcset: 'https://placedog.net/991/400',
21
+ },
22
+ {
23
+ media: MEDIA.SM,
24
+ srcset: 'https://placedog.net/767/400',
25
+ },
26
+ ];
27
+
28
+ const formatSnippet = (code: string, context: StoryContext) => {
29
+ const { args } = context;
30
+ const argsWithValues: string[] = [`alt="${args.alt}"`];
31
+ const hasSources = args.sources !== null;
32
+ const hasSourcesLength = hasSources ? (args.sources as any).length > 0 : false;
33
+
34
+ if (args.isLazy !== undefined) argsWithValues.push(`:is-lazy="${args.isLazy}"`);
35
+ if (hasSources && hasSourcesLength) argsWithValues.push(`:sources="sources"`);
36
+ if (args.src) argsWithValues.push(`:src="${args.src}"`);
37
+
38
+ return `<TideImage ${argsWithValues.join(' ')} />`;
39
+ };
40
+
41
+ const parameters = {
42
+ docs: {
43
+ source: {
44
+ format: 'vue',
45
+ language: 'html',
46
+ transform: formatSnippet,
47
+ },
48
+ },
49
+ };
3
50
 
4
51
  export default {
5
52
  argTypes: {
@@ -15,6 +62,15 @@ export default {
15
62
  ...argTypeBooleanUnrequired,
16
63
  description: `Determines whether to delay loading until image is in viewport.`,
17
64
  },
65
+ sources: {
66
+ control: 'object',
67
+ description: `Determines image sources by breakpoint.`,
68
+ isCustom: true,
69
+ table: {
70
+ defaultValue: { summary: 'None' },
71
+ type: { summary: 'Source[]' },
72
+ },
73
+ },
18
74
  src: {
19
75
  control: 'text',
20
76
  description: `Image URL.`,
@@ -27,7 +83,8 @@ export default {
27
83
  args: {
28
84
  alt: '',
29
85
  isLazy: undefined,
30
- src: '',
86
+ sources,
87
+ src: 'https://placedog.net/375/400',
31
88
  },
32
89
  component: TideImage,
33
90
  parameters,
@@ -0,0 +1,18 @@
1
+ /* eslint-disable vue/sort-keys */
2
+
3
+ export const BREAKPOINT = {
4
+ SM: 'sm',
5
+ MD: 'md',
6
+ LG: 'lg',
7
+ XL: 'xl',
8
+ } as const;
9
+
10
+ export const MEDIA = {
11
+ SM: 768,
12
+ MD: 992,
13
+ LG: 1232,
14
+ XL: 1920,
15
+ };
16
+
17
+ export type Breakpoint = (typeof BREAKPOINT)[keyof typeof BREAKPOINT];
18
+ export type Media = (typeof MEDIA)[keyof typeof MEDIA];
@@ -0,0 +1,6 @@
1
+ import type { Media } from '@/types/Breakpoint';
2
+
3
+ export type Source = {
4
+ media: Media;
5
+ srcset: string;
6
+ };
@@ -1,13 +1,6 @@
1
1
  /* eslint-disable vue/sort-keys */
2
2
 
3
- export const BREAKPOINT = {
4
- SM: 'sm',
5
- MD: 'md',
6
- LG: 'lg',
7
- XL: 'xl',
8
- } as const;
9
-
10
- export type Breakpoint = (typeof BREAKPOINT)[keyof typeof BREAKPOINT];
3
+ import type { Breakpoint } from '@/types/Breakpoint';
11
4
 
12
5
  export const CSS = {
13
6
  withBreakpoint: (utilities: string[], breakpoint: Breakpoint): string[] => {
@@ -20,8 +13,8 @@ export const CSS = {
20
13
  RIGHT: 'tide-text-right',
21
14
  },
22
15
  Y: {
23
- MIDDLE: 'tide-align-middle',
24
16
  INITIAL: 'tide-align-initial',
17
+ MIDDLE: 'tide-align-middle',
25
18
  },
26
19
  },
27
20
  AXIS1: {