@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.
- package/CHANGELOG.md +35 -2
- package/lib/Box/Box.js +17 -6
- package/lib/ExpandCollapse/Panel.js +1 -1
- package/lib/FlexGrid/Col/Col.js +42 -19
- package/lib/FlexGrid/FlexGrid.js +40 -17
- package/lib/FlexGrid/Row/Row.js +45 -22
- package/lib/Footnote/Footnote.js +328 -0
- package/lib/Footnote/FootnoteLink.js +108 -0
- package/lib/Footnote/dictionary.js +19 -0
- package/lib/Footnote/index.js +12 -0
- package/lib/Listbox/ListboxGroup.js +7 -1
- package/lib/MultiSelectFilter/MultiSelectFilter.js +1 -0
- package/lib/Notification/Notification.js +13 -5
- package/lib/OrderedList/ItemBase.js +7 -1
- package/lib/Responsive/Responsive.js +32 -14
- package/lib/Responsive/ResponsiveProp.js +46 -0
- package/lib/Responsive/ResponsiveWithMediaQueryStyleSheet.js +75 -0
- package/lib/ThemeProvider/ThemeProvider.js +5 -2
- package/lib/ThemeProvider/index.js +9 -1
- package/lib/ThemeProvider/useResponsiveThemeTokens.js +89 -0
- package/lib/Typography/Typography.js +50 -22
- package/lib/index.js +8 -0
- package/lib/server.js +40 -0
- package/lib/utils/ssr-media-query/utils/create-media-query-styles.js +39 -6
- package/lib-module/Box/Box.js +17 -6
- package/lib-module/ExpandCollapse/Panel.js +1 -1
- package/lib-module/FlexGrid/Col/Col.js +42 -19
- package/lib-module/FlexGrid/FlexGrid.js +40 -17
- package/lib-module/FlexGrid/Row/Row.js +45 -22
- package/lib-module/Footnote/Footnote.js +319 -0
- package/lib-module/Footnote/FootnoteLink.js +101 -0
- package/lib-module/Footnote/dictionary.js +12 -0
- package/lib-module/Footnote/index.js +4 -0
- package/lib-module/Listbox/ListboxGroup.js +7 -1
- package/lib-module/MultiSelectFilter/MultiSelectFilter.js +1 -0
- package/lib-module/Notification/Notification.js +13 -5
- package/lib-module/OrderedList/ItemBase.js +7 -1
- package/lib-module/Responsive/Responsive.js +32 -15
- package/lib-module/Responsive/ResponsiveProp.js +39 -0
- package/lib-module/Responsive/ResponsiveWithMediaQueryStyleSheet.js +67 -0
- package/lib-module/ThemeProvider/ThemeProvider.js +5 -2
- package/lib-module/ThemeProvider/index.js +1 -0
- package/lib-module/ThemeProvider/useResponsiveThemeTokens.js +81 -0
- package/lib-module/Typography/Typography.js +52 -24
- package/lib-module/index.js +1 -0
- package/lib-module/server.js +4 -0
- package/lib-module/utils/ssr-media-query/utils/create-media-query-styles.js +36 -6
- package/package.json +13 -2
- package/src/Box/Box.jsx +35 -17
- package/src/ExpandCollapse/Panel.jsx +1 -1
- package/src/FlexGrid/Col/Col.jsx +42 -13
- package/src/FlexGrid/FlexGrid.jsx +40 -11
- package/src/FlexGrid/Row/Row.jsx +40 -16
- package/src/Footnote/Footnote.jsx +316 -0
- package/src/Footnote/FootnoteLink.jsx +95 -0
- package/src/Footnote/dictionary.js +12 -0
- package/src/Footnote/index.js +6 -0
- package/src/Listbox/ListboxGroup.jsx +9 -2
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +2 -0
- package/src/Notification/Notification.jsx +15 -3
- package/src/OrderedList/ItemBase.jsx +14 -2
- package/src/Responsive/Responsive.jsx +31 -12
- package/src/Responsive/ResponsiveProp.jsx +33 -0
- package/src/Responsive/ResponsiveWithMediaQueryStyleSheet.jsx +60 -0
- package/src/ThemeProvider/ThemeProvider.jsx +5 -2
- package/src/ThemeProvider/index.js +1 -0
- package/src/ThemeProvider/useResponsiveThemeTokens.js +85 -0
- package/src/Typography/Typography.jsx +77 -24
- package/src/index.js +1 -0
- package/src/server.js +4 -0
- package/src/utils/ssr-media-query/utils/create-media-query-styles.js +21 -6
|
@@ -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:
|
|
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) =>
|
|
18
|
-
|
|
19
|
-
|
|
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:
|
|
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 {
|
|
4
|
-
import
|
|
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
|
-
*
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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(
|
|
33
|
-
|
|
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
|
|
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
|
});
|
package/lib-module/index.js
CHANGED
|
@@ -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
|
-
|
|
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 {
|
|
12
|
-
* @
|
|
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
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
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.
|
|
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.
|
|
88
|
+
"version": "1.74.0"
|
|
78
89
|
}
|