@telus-uds/components-base 1.72.0 → 1.74.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +35 -2
  2. package/lib/Box/Box.js +17 -6
  3. package/lib/ExpandCollapse/Panel.js +1 -1
  4. package/lib/FlexGrid/Col/Col.js +42 -19
  5. package/lib/FlexGrid/FlexGrid.js +40 -17
  6. package/lib/FlexGrid/Row/Row.js +45 -22
  7. package/lib/Footnote/Footnote.js +328 -0
  8. package/lib/Footnote/FootnoteLink.js +108 -0
  9. package/lib/Footnote/dictionary.js +19 -0
  10. package/lib/Footnote/index.js +12 -0
  11. package/lib/Listbox/ListboxGroup.js +7 -1
  12. package/lib/MultiSelectFilter/MultiSelectFilter.js +1 -0
  13. package/lib/Notification/Notification.js +13 -5
  14. package/lib/OrderedList/ItemBase.js +7 -1
  15. package/lib/Responsive/Responsive.js +32 -14
  16. package/lib/Responsive/ResponsiveProp.js +46 -0
  17. package/lib/Responsive/ResponsiveWithMediaQueryStyleSheet.js +75 -0
  18. package/lib/ThemeProvider/ThemeProvider.js +5 -2
  19. package/lib/ThemeProvider/index.js +9 -1
  20. package/lib/ThemeProvider/useResponsiveThemeTokens.js +89 -0
  21. package/lib/Typography/Typography.js +50 -22
  22. package/lib/index.js +8 -0
  23. package/lib/server.js +40 -0
  24. package/lib/utils/ssr-media-query/utils/create-media-query-styles.js +39 -6
  25. package/lib-module/Box/Box.js +17 -6
  26. package/lib-module/ExpandCollapse/Panel.js +1 -1
  27. package/lib-module/FlexGrid/Col/Col.js +42 -19
  28. package/lib-module/FlexGrid/FlexGrid.js +40 -17
  29. package/lib-module/FlexGrid/Row/Row.js +45 -22
  30. package/lib-module/Footnote/Footnote.js +319 -0
  31. package/lib-module/Footnote/FootnoteLink.js +101 -0
  32. package/lib-module/Footnote/dictionary.js +12 -0
  33. package/lib-module/Footnote/index.js +4 -0
  34. package/lib-module/Listbox/ListboxGroup.js +7 -1
  35. package/lib-module/MultiSelectFilter/MultiSelectFilter.js +1 -0
  36. package/lib-module/Notification/Notification.js +13 -5
  37. package/lib-module/OrderedList/ItemBase.js +7 -1
  38. package/lib-module/Responsive/Responsive.js +32 -15
  39. package/lib-module/Responsive/ResponsiveProp.js +39 -0
  40. package/lib-module/Responsive/ResponsiveWithMediaQueryStyleSheet.js +67 -0
  41. package/lib-module/ThemeProvider/ThemeProvider.js +5 -2
  42. package/lib-module/ThemeProvider/index.js +1 -0
  43. package/lib-module/ThemeProvider/useResponsiveThemeTokens.js +81 -0
  44. package/lib-module/Typography/Typography.js +52 -24
  45. package/lib-module/index.js +1 -0
  46. package/lib-module/server.js +4 -0
  47. package/lib-module/utils/ssr-media-query/utils/create-media-query-styles.js +36 -6
  48. package/package.json +13 -2
  49. package/src/Box/Box.jsx +35 -17
  50. package/src/ExpandCollapse/Panel.jsx +1 -1
  51. package/src/FlexGrid/Col/Col.jsx +42 -13
  52. package/src/FlexGrid/FlexGrid.jsx +40 -11
  53. package/src/FlexGrid/Row/Row.jsx +40 -16
  54. package/src/Footnote/Footnote.jsx +316 -0
  55. package/src/Footnote/FootnoteLink.jsx +95 -0
  56. package/src/Footnote/dictionary.js +12 -0
  57. package/src/Footnote/index.js +6 -0
  58. package/src/Listbox/ListboxGroup.jsx +9 -2
  59. package/src/MultiSelectFilter/MultiSelectFilter.jsx +2 -0
  60. package/src/Notification/Notification.jsx +15 -3
  61. package/src/OrderedList/ItemBase.jsx +14 -2
  62. package/src/Responsive/Responsive.jsx +31 -12
  63. package/src/Responsive/ResponsiveProp.jsx +33 -0
  64. package/src/Responsive/ResponsiveWithMediaQueryStyleSheet.jsx +60 -0
  65. package/src/ThemeProvider/ThemeProvider.jsx +5 -2
  66. package/src/ThemeProvider/index.js +1 -0
  67. package/src/ThemeProvider/useResponsiveThemeTokens.js +85 -0
  68. package/src/Typography/Typography.jsx +77 -24
  69. package/src/index.js +1 -0
  70. package/src/server.js +4 -0
  71. package/src/utils/ssr-media-query/utils/create-media-query-styles.js +21 -6
@@ -0,0 +1,4 @@
1
+ import Footnote from './Footnote';
2
+ import FootnoteLink from './FootnoteLink';
3
+ Footnote.Link = FootnoteLink;
4
+ export default Footnote;
@@ -3,6 +3,7 @@ import React, { forwardRef } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import View from "react-native-web/dist/exports/View";
5
5
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
6
+ import Platform from "react-native-web/dist/exports/Platform";
6
7
  import { withLinkRouter } from '../utils';
7
8
  import ExpandCollapse from '../ExpandCollapse';
8
9
  import ListboxItem from './ListboxItem';
@@ -20,6 +21,11 @@ const styles = StyleSheet.create({
20
21
  padding: 0
21
22
  }
22
23
  });
24
+ const getAccessibilityRole = () => Platform.select({
25
+ ios: 'listitem',
26
+ android: 'none',
27
+ web: 'listitem'
28
+ });
23
29
  const ListboxGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
24
30
  let {
25
31
  id,
@@ -40,7 +46,7 @@ const ListboxGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
40
46
  return /*#__PURE__*/_jsx(View, {
41
47
  id: "test",
42
48
  style: styles.groupWrapper,
43
- accessibilityRole: "listitem",
49
+ accessibilityRole: getAccessibilityRole(),
44
50
  children: /*#__PURE__*/_jsx(ExpandCollapse.Panel, {
45
51
  panelId: id ?? label,
46
52
  controlTokens: {
@@ -98,6 +98,7 @@ const MultiSelectFilter = _ref3 => {
98
98
  if (colSize === 1) return setMaxWidth(false);
99
99
  return colSize === 2 && setMaxWidth(true);
100
100
  }, [colSize]);
101
+ useEffect(() => setCheckedIds(currentValues ?? []), [currentValues]);
101
102
  const {
102
103
  headerFontColor,
103
104
  headerFontSize,
@@ -14,10 +14,18 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
14
14
  const selectContainerStyles = tokens => ({
15
15
  ...tokens
16
16
  });
17
- const selectTextStyles = (tokens, themeOptions) => applyTextStyles({
18
- ...selectTokens('Typography', tokens),
19
- themeOptions
20
- });
17
+ const selectTextStyles = (tokens, themeOptions, isDismissible) => {
18
+ const textTokens = selectTokens('Typography', tokens);
19
+ const styles = {
20
+ ...textTokens,
21
+ themeOptions,
22
+ overflow: 'hidden'
23
+ };
24
+ if (!isDismissible) {
25
+ styles.flexShrink = 1;
26
+ }
27
+ return applyTextStyles(styles);
28
+ };
21
29
  const selectIconProps = _ref => {
22
30
  let {
23
31
  iconSize,
@@ -138,7 +146,7 @@ const Notification = /*#__PURE__*/forwardRef((_ref5, ref) => {
138
146
  if (isDismissed) {
139
147
  return null;
140
148
  }
141
- const textStyles = selectTextStyles(themeTokens, themeOptions);
149
+ const textStyles = selectTextStyles(themeTokens, themeOptions, dismissible);
142
150
  const content = wrapStringsInText(typeof children === 'function' ? children({
143
151
  textStyles,
144
152
  variant
@@ -3,7 +3,13 @@ import React, { forwardRef } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import View from "react-native-web/dist/exports/View";
5
5
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
6
+ import Platform from "react-native-web/dist/exports/Platform";
6
7
  import { jsx as _jsx } from "react/jsx-runtime";
8
+ const getAccessibilityRole = () => Platform.select({
9
+ ios: 'listitem',
10
+ android: 'none',
11
+ web: 'listitem'
12
+ });
7
13
  const Item = /*#__PURE__*/forwardRef((_ref, ref) => {
8
14
  let {
9
15
  children,
@@ -11,7 +17,7 @@ const Item = /*#__PURE__*/forwardRef((_ref, ref) => {
11
17
  ...rest
12
18
  } = _ref;
13
19
  return /*#__PURE__*/_jsx(View, {
14
- accessibilityRole: "listitem",
20
+ accessibilityRole: getAccessibilityRole(),
15
21
  ref: ref,
16
22
  style: [staticStyles.container, style],
17
23
  ...rest,
@@ -1,38 +1,49 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { viewports } from '@telus-uds/system-constants';
4
- import { useResponsiveProp } from '../utils';
3
+ import { useTheme } from '../ThemeProvider';
4
+ import ResponsiveProp from './ResponsiveProp';
5
+ import ResponsiveWithMediaQueryStyleSheet from './ResponsiveWithMediaQueryStyleSheet';
5
6
 
6
7
  /**
7
8
  * Responsive conditionally renders children based on whether the viewport matches the provided
8
9
  * min and max viewports.
9
10
  *
10
- * In SSR, like other viewport utilities, it treats the viewport as `xs` both in SSR itself and
11
+ * If enableMediaQueryStyleSheet themeOption is set to false in ThemeProvider, then in SSR,
12
+ * like other viewport utilities, it treats the viewport as `xs` both in SSR itself and
11
13
  * during first hydration on the client side; then if the viewport is not `xs`, it re-renders
12
14
  * after hydration. This may cause a layout shift on devices other than the narrowest.
15
+ *
16
+ * If enableMediaQueryStyleSheet themeOption is set to true in ThemeProvider, then media query stylesheet
17
+ * is used to hide and show children of `Responsive` within a View.
13
18
  */
14
- import { Fragment as _Fragment } from "react/jsx-runtime";
15
19
  import { jsx as _jsx } from "react/jsx-runtime";
16
20
  const Responsive = _ref => {
17
21
  let {
18
22
  min = 'xs',
19
23
  max,
24
+ inheritedStyles = [],
20
25
  children
21
26
  } = _ref;
22
- // Start returning children at the 'min' viewport or greater
23
- const byViewports = {
24
- [min]: children
25
- };
26
- if (max && max !== 'xl') {
27
- // Stop returning children at the viewport one above 'max' or greater
28
- const maxIndex = viewports.keys.indexOf(max);
29
- const maxPlusOne = maxIndex >= 0 ? viewports.keys[maxIndex + 1] : null;
30
- if (maxPlusOne) byViewports[maxPlusOne] = null;
27
+ const {
28
+ themeOptions: {
29
+ enableMediaQueryStyleSheet
30
+ }
31
+ } = useTheme();
32
+ if (enableMediaQueryStyleSheet) {
33
+ return /*#__PURE__*/_jsx(ResponsiveWithMediaQueryStyleSheet, {
34
+ inheritedStyles: inheritedStyles,
35
+ min: min,
36
+ max: max,
37
+ children: children
38
+ });
31
39
  }
32
- return /*#__PURE__*/_jsx(_Fragment, {
33
- children: useResponsiveProp(byViewports, null)
40
+ return /*#__PURE__*/_jsx(ResponsiveProp, {
41
+ min: min,
42
+ max: max,
43
+ children: children
34
44
  });
35
45
  };
46
+ Responsive.displayName = 'Responsive';
36
47
  Responsive.propTypes = {
37
48
  /**
38
49
  * To hide children of `Responsive` if the current viewport is smaller than `min`
@@ -42,6 +53,12 @@ Responsive.propTypes = {
42
53
  * To hide children of `Responsive` if the current viewport is larger than `max`
43
54
  */
44
55
  max: PropTypes.oneOf(['sm', 'md', 'lg', 'xl']),
56
+ /**
57
+ * Styles to be inherited by `Responsive`.
58
+ * It should be an array of style property names.
59
+ * Note: This prop is only applicable when `enableMediaQueryStylesheet` is set to true in the `ThemeProvider`.
60
+ */
61
+ inheritedStyles: PropTypes.arrayOf(PropTypes.string),
45
62
  children: PropTypes.node.isRequired
46
63
  };
47
64
  export default Responsive;
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { viewports } from '@telus-uds/system-constants';
4
+ import { useResponsiveProp } from '../utils';
5
+ import { Fragment as _Fragment } from "react/jsx-runtime";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ const ResponsiveProp = _ref => {
8
+ let {
9
+ min = 'xs',
10
+ max,
11
+ children
12
+ } = _ref;
13
+ const byViewports = {
14
+ [min]: children
15
+ };
16
+ if (max && max !== 'xl') {
17
+ // Stop returning children at the viewport one above 'max' or greater
18
+ const maxIndex = viewports.keys.indexOf(max);
19
+ const maxPlusOne = maxIndex >= 0 ? viewports.keys[maxIndex + 1] : null;
20
+ if (maxPlusOne) byViewports[maxPlusOne] = null;
21
+ }
22
+ const responsiveProp = useResponsiveProp(byViewports, null);
23
+ return /*#__PURE__*/_jsx(_Fragment, {
24
+ children: responsiveProp
25
+ });
26
+ };
27
+ ResponsiveProp.displayName = 'Responsive';
28
+ ResponsiveProp.propTypes = {
29
+ /**
30
+ * To hide children of `Responsive` if the current viewport is smaller than `min`
31
+ */
32
+ min: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
33
+ /**
34
+ * To hide children of `Responsive` if the current viewport is larger than `max`
35
+ */
36
+ max: PropTypes.oneOf(['sm', 'md', 'lg', 'xl']),
37
+ children: PropTypes.node.isRequired
38
+ };
39
+ export default ResponsiveProp;
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { viewports } from '@telus-uds/system-constants';
4
+ import { BaseView, StyleSheet, createMediaQueryStyles } from '../utils';
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ function generateResponsiveStyles(min, max) {
7
+ const viewportsArray = viewports.keys;
8
+ const minIndex = viewportsArray.indexOf(min);
9
+ const maxIndex = viewportsArray.indexOf(max);
10
+ let hiddenViewports = [];
11
+ if (minIndex !== -1) {
12
+ hiddenViewports = viewportsArray.slice(0, minIndex);
13
+ }
14
+ if (maxIndex !== -1) {
15
+ hiddenViewports = hiddenViewports.concat(viewportsArray.slice(maxIndex + 1));
16
+ }
17
+ const styles = {};
18
+ viewportsArray.forEach(viewport => {
19
+ if (hiddenViewports.includes(viewport)) {
20
+ styles[viewport] = {
21
+ display: 'none'
22
+ };
23
+ }
24
+ });
25
+ return createMediaQueryStyles(styles, false);
26
+ }
27
+ const ResponsiveWithMediaQueryStyleSheet = _ref => {
28
+ let {
29
+ min,
30
+ max,
31
+ inheritedStyles = [],
32
+ children
33
+ } = _ref;
34
+ const {
35
+ ids,
36
+ styles
37
+ } = StyleSheet.create({
38
+ responsive: {
39
+ ...inheritedStyles.reduce((acc, prop) => {
40
+ acc[prop] = 'inherit';
41
+ return acc;
42
+ }, {}),
43
+ ...generateResponsiveStyles(min, max)
44
+ }
45
+ });
46
+ return /*#__PURE__*/_jsx(BaseView, {
47
+ style: styles.responsive,
48
+ dataSet: ids.responsive && {
49
+ media: ids.responsive
50
+ },
51
+ children: children
52
+ });
53
+ };
54
+ ResponsiveWithMediaQueryStyleSheet.displayName = 'Responsive';
55
+ ResponsiveWithMediaQueryStyleSheet.propTypes = {
56
+ /**
57
+ * To hide children of `Responsive` if the current viewport is smaller than `min`
58
+ */
59
+ min: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
60
+ /**
61
+ * To hide children of `Responsive` if the current viewport is larger than `max`
62
+ */
63
+ max: PropTypes.oneOf(['sm', 'md', 'lg', 'xl']),
64
+ inheritedStyles: PropTypes.arrayOf(PropTypes.string),
65
+ children: PropTypes.node.isRequired
66
+ };
67
+ export default ResponsiveWithMediaQueryStyleSheet;
@@ -15,7 +15,8 @@ const defaultThemeOptions = {
15
15
  // TODO: switch `forceZIndex` to be false by default in the next major version
16
16
  forceZIndex: true,
17
17
  // TODO: switch `enableHelmetSSR` to be false by default in the next major version
18
- enableHelmetSSR: true
18
+ enableHelmetSSR: true,
19
+ enableMediaQueryStyleSheet: false
19
20
  };
20
21
  const ThemeProvider = _ref => {
21
22
  let {
@@ -70,12 +71,14 @@ ThemeProvider.propTypes = {
70
71
  * - `enableHelmetSSR`: on Web SSR, allows React Helmet to run during server-side rendering. This should be
71
72
  * disabled unless a web app has been specifically configured to stop React Helmet accumulating
72
73
  * instances (which may cause a memory leak). See React Helmet's docs: https://github.com/nfl/react-helmet
74
+ * - `enableMediaQueryStyleSheet`: enables the use of Media Query StyleSheet.
73
75
  */
74
76
  themeOptions: PropTypes.shape({
75
77
  forceAbsoluteFontSizing: PropTypes.bool,
76
78
  forceZIndex: PropTypes.bool,
77
79
  enableHelmetSSR: PropTypes.bool,
78
- contentMaxWidth: responsiveProps.getTypeOptionallyByViewport(PropTypes.number)
80
+ contentMaxWidth: responsiveProps.getTypeOptionallyByViewport(PropTypes.number),
81
+ enableMediaQueryStyleSheet: PropTypes.bool
79
82
  })
80
83
  };
81
84
  export default ThemeProvider;
@@ -1,6 +1,7 @@
1
1
  import ThemeProvider from './ThemeProvider';
2
2
  export { default as useTheme } from './useTheme';
3
3
  export { default as useSetTheme } from './useSetTheme';
4
+ export { default as useResponsiveThemeTokens } from './useResponsiveThemeTokens';
4
5
  export * from './useThemeTokens';
5
6
  export * from './utils';
6
7
  export default ThemeProvider;
@@ -0,0 +1,81 @@
1
+ import { viewports } from '@telus-uds/system-constants';
2
+ import useTheme from './useTheme';
3
+ import { getComponentTheme, mergeAppearances, resolveThemeTokens } from './utils';
4
+ const getResponsiveThemeTokens = function (_ref, tokensProp) {
5
+ let {
6
+ rules = [],
7
+ tokens: defaultThemeTokens = {}
8
+ } = _ref;
9
+ let variants = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
10
+ let states = arguments.length > 3 ? arguments[3] : undefined;
11
+ const appearances = mergeAppearances(variants, states);
12
+ const tokensByViewport = Object.fromEntries(viewports.keys.map(viewport => [viewport, {
13
+ ...defaultThemeTokens
14
+ }]));
15
+
16
+ // Go through each rule and collect them for the corresponding viewport if they apply
17
+ rules.forEach(rule => {
18
+ if (doesRuleApply(rule, appearances)) {
19
+ // If the rule does not have a viewport specified, we collect it in all viewports
20
+ let targetViewports = rule.if.viewport || viewports.keys;
21
+ if (!Array.isArray(targetViewports)) {
22
+ targetViewports = [targetViewports];
23
+ }
24
+ targetViewports.forEach(viewport => {
25
+ tokensByViewport[viewport] = {
26
+ ...tokensByViewport[viewport],
27
+ ...rule.tokens
28
+ };
29
+ });
30
+ }
31
+ });
32
+ Object.keys(tokensByViewport).forEach(viewport => {
33
+ tokensByViewport[viewport] = resolveThemeTokens(tokensByViewport[viewport], appearances, tokensProp);
34
+ });
35
+ return tokensByViewport;
36
+ };
37
+ const doesRuleApply = (rule, appearances) => Object.entries(rule.if).every(condition => doesConditionApply(condition, appearances));
38
+ const doesConditionApply = (_ref2, appearances) => {
39
+ let [key, value] = _ref2;
40
+ if (key === 'viewport') {
41
+ return true;
42
+ }
43
+ // use null rather than undefined so we can serialise the value in themes
44
+ const appearanceValue = appearances[key] ?? null;
45
+ return Array.isArray(value) ? value.includes(appearanceValue) : value === appearanceValue;
46
+ };
47
+
48
+ /**
49
+ * @typedef {import('../utils/props/tokens.js').TokensSet} TokensSet
50
+ * @typedef {import('../utils/props/tokens.js').TokensProp} TokensProp
51
+ * @typedef {import('../utils/props/variantProp').AppearanceSet} AppearanceSet
52
+ *
53
+ * Returns a complete set of tokens for a component for each viewport based on which of the
54
+ * component's theme rules apply to the current set of theme appearances.
55
+ * Pass the returned output to createMediaQueryStyles to generate media query styles for use inside
56
+ * the media query stylesheet from './utils/ssr-media-query'.
57
+ *
58
+ * @typedef {Object} ResponsiveObject
59
+ * @property {TokensSet} xs
60
+ * @property {TokensSet} sm
61
+ * @property {TokensSet} md
62
+ * @property {TokensSet} lg
63
+ * @property {TokensSet} xl
64
+ *
65
+ * @param { string } componentName
66
+ * @param { TokensProp } tokens
67
+ * @param { AppearanceSet } variants
68
+ * @param { AppearanceSet } states
69
+ * @returns { ResponsiveObject }
70
+ */
71
+
72
+ const useResponsiveThemeTokens = function (componentName) {
73
+ let tokens = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
74
+ let variants = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
75
+ let states = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
76
+ const theme = useTheme();
77
+ const componentTheme = getComponentTheme(theme, componentName);
78
+ const themeTokens = getResponsiveThemeTokens(componentTheme, tokens, variants, states);
79
+ return themeTokens;
80
+ };
81
+ export default useResponsiveThemeTokens;
@@ -2,10 +2,10 @@ import React, { forwardRef } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import Text from "react-native-web/dist/exports/Text";
4
4
  import View from "react-native-web/dist/exports/View";
5
- import { useTheme, useThemeTokens } from '../ThemeProvider';
6
- import { useViewport } from '../ViewportProvider';
5
+ import { useResponsiveThemeTokens, useTheme, useThemeTokens } from '../ThemeProvider';
7
6
  import { applyTextStyles } from '../ThemeProvider/utils';
8
- import { a11yProps, variantProp, getTokensPropType, getMaxFontMultiplier, headingTags, selectSystemProps, textTags, textProps, viewProps, getA11yPropsFromHtmlTag } from '../utils';
7
+ import { a11yProps, variantProp, getTokensPropType, getMaxFontMultiplier, headingTags, selectSystemProps, textTags, textProps, viewProps, getA11yPropsFromHtmlTag, StyleSheet, createMediaQueryStyles } from '../utils';
8
+ import { useViewport } from '../ViewportProvider';
9
9
  /**
10
10
  * @typedef {import('../utils/a11y/semantics').TextTag} TextTag
11
11
  */
@@ -21,7 +21,8 @@ const selectTextStyles = (_ref, themeOptions) => {
21
21
  fontName,
22
22
  textAlign,
23
23
  textTransform,
24
- letterSpacing
24
+ letterSpacing,
25
+ textDecorationLine
25
26
  } = _ref;
26
27
  return applyTextStyles({
27
28
  fontWeight,
@@ -32,7 +33,8 @@ const selectTextStyles = (_ref, themeOptions) => {
32
33
  themeOptions,
33
34
  textAlign,
34
35
  textTransform,
35
- letterSpacing
36
+ letterSpacing,
37
+ textDecorationLine
36
38
  });
37
39
  };
38
40
 
@@ -52,23 +54,50 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
52
54
  ...rest
53
55
  } = _ref2;
54
56
  const viewport = useViewport();
55
- const {
56
- superScriptFontSize,
57
- ...themeTokens
58
- } = useThemeTokens('Typography', tokens, variant, {
59
- viewport
60
- });
61
57
  const {
62
58
  themeOptions
63
59
  } = useTheme();
60
+ const {
61
+ enableMediaQueryStyleSheet
62
+ } = themeOptions;
63
+ const useTokens = enableMediaQueryStyleSheet ? useResponsiveThemeTokens : useThemeTokens;
64
+ const themeTokens = useTokens('Typography', tokens, variant, !enableMediaQueryStyleSheet && {
65
+ viewport
66
+ });
67
+ const maxFontSizeMultiplier = enableMediaQueryStyleSheet ? getMaxFontMultiplier(themeTokens[viewport]) : getMaxFontMultiplier(themeTokens);
68
+ const textDecorationLine = strikeThrough ? 'line-through' : 'none';
69
+ let textStyles;
70
+ let mediaIds;
71
+ if (enableMediaQueryStyleSheet) {
72
+ const transformedThemeTokens = Object.entries(themeTokens).reduce((acc, _ref3) => {
73
+ let [vp, viewportTokens] = _ref3;
74
+ acc[vp] = selectTextStyles({
75
+ textAlign: align,
76
+ textDecorationLine,
77
+ ...viewportTokens
78
+ }, themeOptions);
79
+ return acc;
80
+ }, {});
81
+ const mediaQueryStyles = createMediaQueryStyles(transformedThemeTokens);
82
+ const {
83
+ ids,
84
+ styles
85
+ } = StyleSheet.create({
86
+ text: mediaQueryStyles
87
+ });
88
+ textStyles = styles.text;
89
+ mediaIds = ids.text;
90
+ } else {
91
+ textStyles = selectTextStyles({
92
+ textAlign: align,
93
+ textDecorationLine,
94
+ ...themeTokens
95
+ }, themeOptions);
96
+ }
64
97
  const resolvedTextProps = {
65
98
  ...selectTextProps(rest),
66
- style: selectTextStyles(align ? {
67
- ...themeTokens,
68
- textAlign: align
69
- } : themeTokens, themeOptions),
70
99
  dataSet,
71
- maxFontSizeMultiplier: getMaxFontMultiplier(themeTokens)
100
+ maxFontSizeMultiplier
72
101
  };
73
102
  const containerProps = {
74
103
  accessibilityRole,
@@ -79,7 +108,7 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
79
108
  if (typeof child === 'object' && ((child === null || child === void 0 ? void 0 : child.type) === 'sub' || (child === null || child === void 0 ? void 0 : child.type) === 'sup')) {
80
109
  var _child$props;
81
110
  const childStyles = (child === null || child === void 0 ? void 0 : (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.style) || {};
82
- const supFontSize = childStyles.fontSize ?? superScriptFontSize;
111
+ const supFontSize = childStyles.fontSize ?? themeTokens.superScriptFontSize;
83
112
  const sanitizedChild = /*#__PURE__*/React.cloneElement(child, {
84
113
  style: {
85
114
  ...childStyles,
@@ -99,19 +128,15 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
99
128
  }
100
129
  return resetTagStyling(children);
101
130
  };
102
- const textDecorationLine = strikeThrough ? 'line-through' : 'none';
103
- const textStyles = resolvedTextProps.style ? {
104
- ...resolvedTextProps.style,
105
- textDecorationLine
106
- } : {
107
- textDecorationLine
108
- };
109
131
  return block ? /*#__PURE__*/_jsx(View, {
110
132
  ref: ref,
111
133
  ...containerProps,
112
134
  children: /*#__PURE__*/_jsx(Text, {
113
135
  ...resolvedTextProps,
114
136
  style: textStyles,
137
+ dataSet: mediaIds && {
138
+ media: mediaIds
139
+ },
115
140
  children: sanitizeChildren(children)
116
141
  })
117
142
  }) : /*#__PURE__*/_jsx(Text, {
@@ -119,6 +144,9 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
119
144
  ...containerProps,
120
145
  ...resolvedTextProps,
121
146
  style: textStyles,
147
+ dataSet: mediaIds && {
148
+ media: mediaIds
149
+ },
122
150
  children: sanitizeChildren(children)
123
151
  });
124
152
  });
@@ -17,6 +17,7 @@ export { default as ExpandCollapse, Accordion } from './ExpandCollapse';
17
17
  export { default as Feedback } from './Feedback';
18
18
  export { default as Fieldset } from './Fieldset';
19
19
  export { default as FlexGrid } from './FlexGrid';
20
+ export { default as Footnote } from './Footnote';
20
21
  export { default as HorizontalScroll } from './HorizontalScroll';
21
22
  export * from './HorizontalScroll';
22
23
  export { default as Icon } from './Icon';
@@ -0,0 +1,4 @@
1
+ export { default as selectSystemProps } from './utils/props/selectSystemProps';
2
+ export { getTokensPropType } from './utils/props/tokens';
3
+ export { default as htmlAttrs } from './utils/htmlAttrs';
4
+ export { getComponentTheme, getThemeTokens } from './ThemeProvider/utils/theme-tokens';
@@ -1,21 +1,51 @@
1
1
  import { viewports } from '@telus-uds/system-constants';
2
+ const inherit = _ref => {
3
+ let {
4
+ xs,
5
+ sm = xs,
6
+ md = sm,
7
+ lg = md,
8
+ xl = lg
9
+ } = _ref;
10
+ return {
11
+ xs,
12
+ sm,
13
+ md,
14
+ lg,
15
+ xl
16
+ };
17
+ };
2
18
 
3
19
  /**
4
20
  * @typedef { Object } CssStyles
5
- * @typedef { Record<"xs" | "sm" | "md" | "lg" | "xl", CssStyles> } ViewportStyles
21
+ */
22
+
23
+ /**
24
+ * @typedef { Object } ViewportStyles
25
+ * @property { CssStyles } xs - The CSS styles for the "xs" viewport (required).
26
+ * @property { CssStyles } [sm] - Optional styles for the "sm" viewport. Inherits from "xs" if not specified.
27
+ * @property { CssStyles } [md] - Optional styles for the "md" viewport. Inherits from "sm" if not specified.
28
+ * @property { CssStyles } [lg] - Optional styles for the "lg" viewport. Inherits from "md" if not specified.
29
+ * @property { CssStyles } [xl] - Optional styles for the "xl" viewport. Inherits from "lg" if not specified.
30
+ */
31
+
32
+ /**
6
33
  * @typedef { Record<String, CssStyles> } MediaQueryStyles
7
34
  */
8
35
 
9
36
  /**
10
37
  * Generates media query styles based on specified viewport styles.
11
- * @param {ViewportStyles} viewportStyles
12
- * @returns { MediaQueryStyles }
38
+ * @param { Object } viewportStyles - The styles for different viewports.
39
+ * @param { boolean } [shouldInherit=true] - Flag indicating whether to inherit styles.
40
+ * @returns { Object } - The media query styles.
13
41
  */
14
42
 
15
43
  function createMediaQueryStyles(viewportStyles) {
16
- const viewportsArray = Object.keys(viewportStyles);
17
- const mediaQueries = Object.entries(viewportStyles).reduce((acc, _ref) => {
18
- let [viewport, styles] = _ref;
44
+ let shouldInherit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
45
+ const effectiveStyles = shouldInherit ? inherit(viewportStyles) : viewportStyles;
46
+ const viewportsArray = viewports.keys;
47
+ const mediaQueries = Object.entries(effectiveStyles).reduce((acc, _ref2) => {
48
+ let [viewport, styles] = _ref2;
19
49
  const minWidth = viewports.map.get(viewport);
20
50
  const nextViewport = viewportsArray[viewportsArray.indexOf(viewport) + 1];
21
51
  const maxWidth = viewports.map.get(nextViewport);
package/package.json CHANGED
@@ -11,9 +11,10 @@
11
11
  "@floating-ui/react-native": "^0.8.1",
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@telus-uds/system-constants": "^1.3.0",
14
- "@telus-uds/system-theme-tokens": "^2.48.0",
14
+ "@telus-uds/system-theme-tokens": "^2.50.0",
15
15
  "airbnb-prop-types": "^2.16.0",
16
16
  "css-mediaquery": "^0.1.2",
17
+ "expo-linear-gradient": "^12.5.0",
17
18
  "lodash.debounce": "^4.0.8",
18
19
  "lodash.merge": "^4.6.2",
19
20
  "lodash.throttle": "^4.1.1",
@@ -38,6 +39,16 @@
38
39
  "lib": "lib",
39
40
  "test": "__tests__"
40
41
  },
42
+ "exports": {
43
+ ".": {
44
+ "import": "./lib-module/index.js",
45
+ "require": "./lib/index.js"
46
+ },
47
+ "./server": {
48
+ "import": "./lib-module/server.js",
49
+ "require": "./lib/server.js"
50
+ }
51
+ },
41
52
  "homepage": "https://github.com/telus/universal-design-system#readme",
42
53
  "keywords": [
43
54
  "base"
@@ -74,5 +85,5 @@
74
85
  "standard-engine": {
75
86
  "skip": true
76
87
  },
77
- "version": "1.72.0"
88
+ "version": "1.74.0"
78
89
  }