@spark-web/text 1.0.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 +17 -0
- package/README.md +137 -0
- package/dist/declarations/src/Strong.d.ts +5 -0
- package/dist/declarations/src/Text.d.ts +32 -0
- package/dist/declarations/src/context.d.ts +11 -0
- package/dist/declarations/src/defaultTextProps.d.ts +16 -0
- package/dist/declarations/src/index.d.ts +11 -0
- package/dist/declarations/src/useForegroundTone.d.ts +3 -0
- package/dist/declarations/src/useOverflowStrategy.d.ts +27 -0
- package/dist/declarations/src/useText.d.ts +29 -0
- package/dist/spark-web-text.cjs.d.ts +1 -0
- package/dist/spark-web-text.cjs.dev.js +266 -0
- package/dist/spark-web-text.cjs.js +7 -0
- package/dist/spark-web-text.cjs.prod.js +266 -0
- package/dist/spark-web-text.esm.js +250 -0
- package/package.json +21 -0
- package/src/Strong.tsx +13 -0
- package/src/Text.stories.tsx +20 -0
- package/src/Text.tsx +113 -0
- package/src/context.ts +13 -0
- package/src/defaultTextProps.tsx +48 -0
- package/src/index.ts +17 -0
- package/src/useForegroundTone.ts +36 -0
- package/src/useOverflowStrategy.ts +28 -0
- package/src/useText.ts +56 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var css = require('@emotion/css');
|
|
7
|
+
var theme = require('@spark-web/theme');
|
|
8
|
+
var box = require('@spark-web/box');
|
|
9
|
+
var ts = require('@spark-web/utils/ts');
|
|
10
|
+
var _defineProperty = require('@babel/runtime/helpers/esm/defineProperty');
|
|
11
|
+
|
|
12
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
13
|
+
|
|
14
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
15
|
+
|
|
16
|
+
var TextContext = /*#__PURE__*/React.createContext(undefined);
|
|
17
|
+
function useTextContext() {
|
|
18
|
+
return React.useContext(TextContext);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var __jsx$2 = React__default["default"].createElement;
|
|
22
|
+
var DefaultTextPropsContext = /*#__PURE__*/React.createContext({
|
|
23
|
+
size: undefined,
|
|
24
|
+
tone: undefined,
|
|
25
|
+
weight: undefined
|
|
26
|
+
});
|
|
27
|
+
function DefaultTextPropsProvider(_ref) {
|
|
28
|
+
var children = _ref.children,
|
|
29
|
+
size = _ref.size,
|
|
30
|
+
tone = _ref.tone,
|
|
31
|
+
weight = _ref.weight;
|
|
32
|
+
var defaultTextProps = React.useMemo(function () {
|
|
33
|
+
return {
|
|
34
|
+
size: size,
|
|
35
|
+
tone: tone,
|
|
36
|
+
weight: weight
|
|
37
|
+
};
|
|
38
|
+
}, [size, tone, weight]);
|
|
39
|
+
return __jsx$2(DefaultTextPropsContext.Provider, {
|
|
40
|
+
value: defaultTextProps
|
|
41
|
+
}, children);
|
|
42
|
+
}
|
|
43
|
+
var useDefaultTextProps = function useDefaultTextProps(_ref2) {
|
|
44
|
+
var _ref3, _ref4, _ref5;
|
|
45
|
+
|
|
46
|
+
var sizeProp = _ref2.size,
|
|
47
|
+
toneProp = _ref2.tone,
|
|
48
|
+
weightProp = _ref2.weight;
|
|
49
|
+
|
|
50
|
+
var _useContext = React.useContext(DefaultTextPropsContext),
|
|
51
|
+
size = _useContext.size,
|
|
52
|
+
tone = _useContext.tone,
|
|
53
|
+
weight = _useContext.weight;
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
size: (_ref3 = sizeProp !== null && sizeProp !== void 0 ? sizeProp : size) !== null && _ref3 !== void 0 ? _ref3 : 'standard',
|
|
57
|
+
tone: (_ref4 = toneProp !== null && toneProp !== void 0 ? toneProp : tone) !== null && _ref4 !== void 0 ? _ref4 : 'neutral',
|
|
58
|
+
weight: (_ref5 = weightProp !== null && weightProp !== void 0 ? weightProp : weight) !== null && _ref5 !== void 0 ? _ref5 : 'regular'
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
var __jsx$1 = React__default["default"].createElement;
|
|
63
|
+
var Strong = function Strong(_ref) {
|
|
64
|
+
var children = _ref.children;
|
|
65
|
+
|
|
66
|
+
var _useTheme = theme.useTheme(),
|
|
67
|
+
typography = _useTheme.typography;
|
|
68
|
+
|
|
69
|
+
var styles = {
|
|
70
|
+
fontWeight: typography.fontWeight.strong
|
|
71
|
+
};
|
|
72
|
+
return __jsx$1("strong", {
|
|
73
|
+
className: css.css(styles)
|
|
74
|
+
}, children);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
var strategyMap = {
|
|
78
|
+
truncate: {
|
|
79
|
+
display: 'block',
|
|
80
|
+
overflow: 'hidden',
|
|
81
|
+
textOverflow: 'ellipsis',
|
|
82
|
+
whiteSpace: 'nowrap'
|
|
83
|
+
},
|
|
84
|
+
nowrap: {
|
|
85
|
+
whiteSpace: 'nowrap'
|
|
86
|
+
},
|
|
87
|
+
// https://css-tricks.com/better-line-breaks-for-long-urls/
|
|
88
|
+
breakword: {
|
|
89
|
+
display: 'block',
|
|
90
|
+
overflowWrap: 'break-word',
|
|
91
|
+
wordBreak: 'break-word',
|
|
92
|
+
wordWrap: 'break-word'
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
function useOverflowStrategy(strategy) {
|
|
96
|
+
if (!strategy) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return strategyMap[strategy];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
var invertableTones = {
|
|
104
|
+
neutral: {
|
|
105
|
+
dark: 'neutralInverted',
|
|
106
|
+
light: 'neutral'
|
|
107
|
+
},
|
|
108
|
+
muted: {
|
|
109
|
+
dark: 'mutedInverted',
|
|
110
|
+
light: 'muted'
|
|
111
|
+
},
|
|
112
|
+
link: {
|
|
113
|
+
dark: 'neutralInverted',
|
|
114
|
+
light: 'link'
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
function useForegroundTone(tone) {
|
|
118
|
+
var theme$1 = theme.useTheme();
|
|
119
|
+
var backgroundLightness = box.useBackgroundLightness();
|
|
120
|
+
|
|
121
|
+
if (tone in invertableTones) {
|
|
122
|
+
return theme$1.color.foreground[invertableTones[tone][backgroundLightness]];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return theme$1.color.foreground[tone];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
129
|
+
|
|
130
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
131
|
+
function useText(_ref) {
|
|
132
|
+
var _ref$baseline = _ref.baseline,
|
|
133
|
+
baseline = _ref$baseline === void 0 ? true : _ref$baseline,
|
|
134
|
+
size = _ref.size,
|
|
135
|
+
tone = _ref.tone,
|
|
136
|
+
weight = _ref.weight;
|
|
137
|
+
|
|
138
|
+
var _useTheme = theme.useTheme(),
|
|
139
|
+
typography = _useTheme.typography,
|
|
140
|
+
utils = _useTheme.utils;
|
|
141
|
+
|
|
142
|
+
var color = useForegroundTone(tone);
|
|
143
|
+
var _typography$text$size = typography.text[size],
|
|
144
|
+
mobile = _typography$text$size.mobile,
|
|
145
|
+
tablet = _typography$text$size.tablet;
|
|
146
|
+
var responsiveStyles = utils.responsiveStyles({
|
|
147
|
+
mobile: createTextStyles(mobile, {
|
|
148
|
+
includeTrims: baseline
|
|
149
|
+
}),
|
|
150
|
+
tablet: createTextStyles(tablet, {
|
|
151
|
+
includeTrims: baseline
|
|
152
|
+
})
|
|
153
|
+
});
|
|
154
|
+
var styles = [{
|
|
155
|
+
color: color,
|
|
156
|
+
fontFamily: typography.fontFamily.sans.name,
|
|
157
|
+
fontWeight: typography.fontWeight[weight]
|
|
158
|
+
}, responsiveStyles];
|
|
159
|
+
return styles;
|
|
160
|
+
}
|
|
161
|
+
function createTextStyles(_ref2) {
|
|
162
|
+
var fontSize = _ref2.fontSize,
|
|
163
|
+
lineHeight = _ref2.lineHeight,
|
|
164
|
+
trims = _ref2.trims;
|
|
165
|
+
|
|
166
|
+
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
167
|
+
_ref3$includeTrims = _ref3.includeTrims,
|
|
168
|
+
includeTrims = _ref3$includeTrims === void 0 ? true : _ref3$includeTrims;
|
|
169
|
+
|
|
170
|
+
var pseudo = {
|
|
171
|
+
content: '" "',
|
|
172
|
+
display: 'table'
|
|
173
|
+
};
|
|
174
|
+
var leadingTrim = includeTrims ? {
|
|
175
|
+
'::before': _objectSpread(_objectSpread({}, pseudo), {}, {
|
|
176
|
+
marginBottom: trims.capHeightTrim
|
|
177
|
+
}),
|
|
178
|
+
'::after': _objectSpread(_objectSpread({}, pseudo), {}, {
|
|
179
|
+
marginTop: trims.baselineTrim
|
|
180
|
+
})
|
|
181
|
+
} : null;
|
|
182
|
+
return _objectSpread({
|
|
183
|
+
fontSize: fontSize,
|
|
184
|
+
lineHeight: lineHeight
|
|
185
|
+
}, leadingTrim);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var __jsx = React__default["default"].createElement;
|
|
189
|
+
var Text = ts.forwardRefWithAs(function (_ref, forwardedRef) {
|
|
190
|
+
var as = _ref.as,
|
|
191
|
+
children = _ref.children,
|
|
192
|
+
id = _ref.id,
|
|
193
|
+
align = _ref.align,
|
|
194
|
+
baselineProp = _ref.baseline,
|
|
195
|
+
inline = _ref.inline,
|
|
196
|
+
overflowStrategy = _ref.overflowStrategy,
|
|
197
|
+
sizeProp = _ref.size,
|
|
198
|
+
tabularNumbers = _ref.tabularNumbers,
|
|
199
|
+
toneProp = _ref.tone,
|
|
200
|
+
transform = _ref.transform,
|
|
201
|
+
weightProp = _ref.weight;
|
|
202
|
+
var overflowStyles = useOverflowStrategy(overflowStrategy);
|
|
203
|
+
var textContext = useTextContext();
|
|
204
|
+
|
|
205
|
+
var _useDefaultTextProps = useDefaultTextProps({
|
|
206
|
+
size: sizeProp !== null && sizeProp !== void 0 ? sizeProp : textContext === null || textContext === void 0 ? void 0 : textContext.size,
|
|
207
|
+
tone: toneProp !== null && toneProp !== void 0 ? toneProp : textContext === null || textContext === void 0 ? void 0 : textContext.tone,
|
|
208
|
+
weight: weightProp !== null && weightProp !== void 0 ? weightProp : textContext === null || textContext === void 0 ? void 0 : textContext.weight
|
|
209
|
+
}),
|
|
210
|
+
size = _useDefaultTextProps.size,
|
|
211
|
+
tone = _useDefaultTextProps.tone,
|
|
212
|
+
weight = _useDefaultTextProps.weight;
|
|
213
|
+
|
|
214
|
+
var baseline = !inline && baselineProp;
|
|
215
|
+
var textStyles = useText({
|
|
216
|
+
baseline: baseline,
|
|
217
|
+
size: size,
|
|
218
|
+
tone: tone,
|
|
219
|
+
weight: weight
|
|
220
|
+
});
|
|
221
|
+
var styles = [textStyles, {
|
|
222
|
+
display: inline ? 'inline' : 'block',
|
|
223
|
+
fontVariantNumeric: tabularNumbers ? 'tabular-nums' : undefined,
|
|
224
|
+
textAlign: align,
|
|
225
|
+
textTransform: transform
|
|
226
|
+
}]; // early exit for inline variant
|
|
227
|
+
|
|
228
|
+
if (inline) {
|
|
229
|
+
return __jsx(box.Box, {
|
|
230
|
+
as: as !== null && as !== void 0 ? as : 'span',
|
|
231
|
+
ref: forwardedRef,
|
|
232
|
+
id: id,
|
|
233
|
+
className: css.css(styles)
|
|
234
|
+
}, children);
|
|
235
|
+
} // prepare block variant
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
var content = overflowStrategy ? __jsx("span", {
|
|
239
|
+
className: css.css(overflowStyles)
|
|
240
|
+
}, children) : children;
|
|
241
|
+
var textContextValue = React.useMemo(function () {
|
|
242
|
+
return {
|
|
243
|
+
size: size,
|
|
244
|
+
tone: tone,
|
|
245
|
+
weight: weight
|
|
246
|
+
};
|
|
247
|
+
}, [size, tone, weight]);
|
|
248
|
+
return __jsx(TextContext.Provider, {
|
|
249
|
+
value: textContextValue
|
|
250
|
+
}, __jsx(box.Box, {
|
|
251
|
+
as: as,
|
|
252
|
+
ref: forwardedRef,
|
|
253
|
+
id: id,
|
|
254
|
+
className: css.css(styles)
|
|
255
|
+
}, content));
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
exports.DefaultTextPropsProvider = DefaultTextPropsProvider;
|
|
259
|
+
exports.Strong = Strong;
|
|
260
|
+
exports.Text = Text;
|
|
261
|
+
exports.createTextStyles = createTextStyles;
|
|
262
|
+
exports.useDefaultTextProps = useDefaultTextProps;
|
|
263
|
+
exports.useForegroundTone = useForegroundTone;
|
|
264
|
+
exports.useOverflowStrategy = useOverflowStrategy;
|
|
265
|
+
exports.useText = useText;
|
|
266
|
+
exports.useTextContext = useTextContext;
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import React, { useContext, createContext, useMemo } from 'react';
|
|
2
|
+
import { css } from '@emotion/css';
|
|
3
|
+
import { useTheme } from '@spark-web/theme';
|
|
4
|
+
import { useBackgroundLightness, Box } from '@spark-web/box';
|
|
5
|
+
import { forwardRefWithAs } from '@spark-web/utils/ts';
|
|
6
|
+
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
7
|
+
|
|
8
|
+
var TextContext = /*#__PURE__*/createContext(undefined);
|
|
9
|
+
function useTextContext() {
|
|
10
|
+
return useContext(TextContext);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
var __jsx$2 = React.createElement;
|
|
14
|
+
var DefaultTextPropsContext = /*#__PURE__*/createContext({
|
|
15
|
+
size: undefined,
|
|
16
|
+
tone: undefined,
|
|
17
|
+
weight: undefined
|
|
18
|
+
});
|
|
19
|
+
function DefaultTextPropsProvider(_ref) {
|
|
20
|
+
var children = _ref.children,
|
|
21
|
+
size = _ref.size,
|
|
22
|
+
tone = _ref.tone,
|
|
23
|
+
weight = _ref.weight;
|
|
24
|
+
var defaultTextProps = useMemo(function () {
|
|
25
|
+
return {
|
|
26
|
+
size: size,
|
|
27
|
+
tone: tone,
|
|
28
|
+
weight: weight
|
|
29
|
+
};
|
|
30
|
+
}, [size, tone, weight]);
|
|
31
|
+
return __jsx$2(DefaultTextPropsContext.Provider, {
|
|
32
|
+
value: defaultTextProps
|
|
33
|
+
}, children);
|
|
34
|
+
}
|
|
35
|
+
var useDefaultTextProps = function useDefaultTextProps(_ref2) {
|
|
36
|
+
var _ref3, _ref4, _ref5;
|
|
37
|
+
|
|
38
|
+
var sizeProp = _ref2.size,
|
|
39
|
+
toneProp = _ref2.tone,
|
|
40
|
+
weightProp = _ref2.weight;
|
|
41
|
+
|
|
42
|
+
var _useContext = useContext(DefaultTextPropsContext),
|
|
43
|
+
size = _useContext.size,
|
|
44
|
+
tone = _useContext.tone,
|
|
45
|
+
weight = _useContext.weight;
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
size: (_ref3 = sizeProp !== null && sizeProp !== void 0 ? sizeProp : size) !== null && _ref3 !== void 0 ? _ref3 : 'standard',
|
|
49
|
+
tone: (_ref4 = toneProp !== null && toneProp !== void 0 ? toneProp : tone) !== null && _ref4 !== void 0 ? _ref4 : 'neutral',
|
|
50
|
+
weight: (_ref5 = weightProp !== null && weightProp !== void 0 ? weightProp : weight) !== null && _ref5 !== void 0 ? _ref5 : 'regular'
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var __jsx$1 = React.createElement;
|
|
55
|
+
var Strong = function Strong(_ref) {
|
|
56
|
+
var children = _ref.children;
|
|
57
|
+
|
|
58
|
+
var _useTheme = useTheme(),
|
|
59
|
+
typography = _useTheme.typography;
|
|
60
|
+
|
|
61
|
+
var styles = {
|
|
62
|
+
fontWeight: typography.fontWeight.strong
|
|
63
|
+
};
|
|
64
|
+
return __jsx$1("strong", {
|
|
65
|
+
className: css(styles)
|
|
66
|
+
}, children);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
var strategyMap = {
|
|
70
|
+
truncate: {
|
|
71
|
+
display: 'block',
|
|
72
|
+
overflow: 'hidden',
|
|
73
|
+
textOverflow: 'ellipsis',
|
|
74
|
+
whiteSpace: 'nowrap'
|
|
75
|
+
},
|
|
76
|
+
nowrap: {
|
|
77
|
+
whiteSpace: 'nowrap'
|
|
78
|
+
},
|
|
79
|
+
// https://css-tricks.com/better-line-breaks-for-long-urls/
|
|
80
|
+
breakword: {
|
|
81
|
+
display: 'block',
|
|
82
|
+
overflowWrap: 'break-word',
|
|
83
|
+
wordBreak: 'break-word',
|
|
84
|
+
wordWrap: 'break-word'
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
function useOverflowStrategy(strategy) {
|
|
88
|
+
if (!strategy) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return strategyMap[strategy];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
var invertableTones = {
|
|
96
|
+
neutral: {
|
|
97
|
+
dark: 'neutralInverted',
|
|
98
|
+
light: 'neutral'
|
|
99
|
+
},
|
|
100
|
+
muted: {
|
|
101
|
+
dark: 'mutedInverted',
|
|
102
|
+
light: 'muted'
|
|
103
|
+
},
|
|
104
|
+
link: {
|
|
105
|
+
dark: 'neutralInverted',
|
|
106
|
+
light: 'link'
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
function useForegroundTone(tone) {
|
|
110
|
+
var theme = useTheme();
|
|
111
|
+
var backgroundLightness = useBackgroundLightness();
|
|
112
|
+
|
|
113
|
+
if (tone in invertableTones) {
|
|
114
|
+
return theme.color.foreground[invertableTones[tone][backgroundLightness]];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return theme.color.foreground[tone];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
121
|
+
|
|
122
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
123
|
+
function useText(_ref) {
|
|
124
|
+
var _ref$baseline = _ref.baseline,
|
|
125
|
+
baseline = _ref$baseline === void 0 ? true : _ref$baseline,
|
|
126
|
+
size = _ref.size,
|
|
127
|
+
tone = _ref.tone,
|
|
128
|
+
weight = _ref.weight;
|
|
129
|
+
|
|
130
|
+
var _useTheme = useTheme(),
|
|
131
|
+
typography = _useTheme.typography,
|
|
132
|
+
utils = _useTheme.utils;
|
|
133
|
+
|
|
134
|
+
var color = useForegroundTone(tone);
|
|
135
|
+
var _typography$text$size = typography.text[size],
|
|
136
|
+
mobile = _typography$text$size.mobile,
|
|
137
|
+
tablet = _typography$text$size.tablet;
|
|
138
|
+
var responsiveStyles = utils.responsiveStyles({
|
|
139
|
+
mobile: createTextStyles(mobile, {
|
|
140
|
+
includeTrims: baseline
|
|
141
|
+
}),
|
|
142
|
+
tablet: createTextStyles(tablet, {
|
|
143
|
+
includeTrims: baseline
|
|
144
|
+
})
|
|
145
|
+
});
|
|
146
|
+
var styles = [{
|
|
147
|
+
color: color,
|
|
148
|
+
fontFamily: typography.fontFamily.sans.name,
|
|
149
|
+
fontWeight: typography.fontWeight[weight]
|
|
150
|
+
}, responsiveStyles];
|
|
151
|
+
return styles;
|
|
152
|
+
}
|
|
153
|
+
function createTextStyles(_ref2) {
|
|
154
|
+
var fontSize = _ref2.fontSize,
|
|
155
|
+
lineHeight = _ref2.lineHeight,
|
|
156
|
+
trims = _ref2.trims;
|
|
157
|
+
|
|
158
|
+
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
159
|
+
_ref3$includeTrims = _ref3.includeTrims,
|
|
160
|
+
includeTrims = _ref3$includeTrims === void 0 ? true : _ref3$includeTrims;
|
|
161
|
+
|
|
162
|
+
var pseudo = {
|
|
163
|
+
content: '" "',
|
|
164
|
+
display: 'table'
|
|
165
|
+
};
|
|
166
|
+
var leadingTrim = includeTrims ? {
|
|
167
|
+
'::before': _objectSpread(_objectSpread({}, pseudo), {}, {
|
|
168
|
+
marginBottom: trims.capHeightTrim
|
|
169
|
+
}),
|
|
170
|
+
'::after': _objectSpread(_objectSpread({}, pseudo), {}, {
|
|
171
|
+
marginTop: trims.baselineTrim
|
|
172
|
+
})
|
|
173
|
+
} : null;
|
|
174
|
+
return _objectSpread({
|
|
175
|
+
fontSize: fontSize,
|
|
176
|
+
lineHeight: lineHeight
|
|
177
|
+
}, leadingTrim);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
var __jsx = React.createElement;
|
|
181
|
+
var Text = forwardRefWithAs(function (_ref, forwardedRef) {
|
|
182
|
+
var as = _ref.as,
|
|
183
|
+
children = _ref.children,
|
|
184
|
+
id = _ref.id,
|
|
185
|
+
align = _ref.align,
|
|
186
|
+
baselineProp = _ref.baseline,
|
|
187
|
+
inline = _ref.inline,
|
|
188
|
+
overflowStrategy = _ref.overflowStrategy,
|
|
189
|
+
sizeProp = _ref.size,
|
|
190
|
+
tabularNumbers = _ref.tabularNumbers,
|
|
191
|
+
toneProp = _ref.tone,
|
|
192
|
+
transform = _ref.transform,
|
|
193
|
+
weightProp = _ref.weight;
|
|
194
|
+
var overflowStyles = useOverflowStrategy(overflowStrategy);
|
|
195
|
+
var textContext = useTextContext();
|
|
196
|
+
|
|
197
|
+
var _useDefaultTextProps = useDefaultTextProps({
|
|
198
|
+
size: sizeProp !== null && sizeProp !== void 0 ? sizeProp : textContext === null || textContext === void 0 ? void 0 : textContext.size,
|
|
199
|
+
tone: toneProp !== null && toneProp !== void 0 ? toneProp : textContext === null || textContext === void 0 ? void 0 : textContext.tone,
|
|
200
|
+
weight: weightProp !== null && weightProp !== void 0 ? weightProp : textContext === null || textContext === void 0 ? void 0 : textContext.weight
|
|
201
|
+
}),
|
|
202
|
+
size = _useDefaultTextProps.size,
|
|
203
|
+
tone = _useDefaultTextProps.tone,
|
|
204
|
+
weight = _useDefaultTextProps.weight;
|
|
205
|
+
|
|
206
|
+
var baseline = !inline && baselineProp;
|
|
207
|
+
var textStyles = useText({
|
|
208
|
+
baseline: baseline,
|
|
209
|
+
size: size,
|
|
210
|
+
tone: tone,
|
|
211
|
+
weight: weight
|
|
212
|
+
});
|
|
213
|
+
var styles = [textStyles, {
|
|
214
|
+
display: inline ? 'inline' : 'block',
|
|
215
|
+
fontVariantNumeric: tabularNumbers ? 'tabular-nums' : undefined,
|
|
216
|
+
textAlign: align,
|
|
217
|
+
textTransform: transform
|
|
218
|
+
}]; // early exit for inline variant
|
|
219
|
+
|
|
220
|
+
if (inline) {
|
|
221
|
+
return __jsx(Box, {
|
|
222
|
+
as: as !== null && as !== void 0 ? as : 'span',
|
|
223
|
+
ref: forwardedRef,
|
|
224
|
+
id: id,
|
|
225
|
+
className: css(styles)
|
|
226
|
+
}, children);
|
|
227
|
+
} // prepare block variant
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
var content = overflowStrategy ? __jsx("span", {
|
|
231
|
+
className: css(overflowStyles)
|
|
232
|
+
}, children) : children;
|
|
233
|
+
var textContextValue = useMemo(function () {
|
|
234
|
+
return {
|
|
235
|
+
size: size,
|
|
236
|
+
tone: tone,
|
|
237
|
+
weight: weight
|
|
238
|
+
};
|
|
239
|
+
}, [size, tone, weight]);
|
|
240
|
+
return __jsx(TextContext.Provider, {
|
|
241
|
+
value: textContextValue
|
|
242
|
+
}, __jsx(Box, {
|
|
243
|
+
as: as,
|
|
244
|
+
ref: forwardedRef,
|
|
245
|
+
id: id,
|
|
246
|
+
className: css(styles)
|
|
247
|
+
}, content));
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
export { DefaultTextPropsProvider, Strong, Text, createTextStyles, useDefaultTextProps, useForegroundTone, useOverflowStrategy, useText, useTextContext };
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@spark-web/text",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"main": "dist/spark-web-text.cjs.js",
|
|
6
|
+
"module": "dist/spark-web-text.esm.js",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@types/react": "^17.0.12"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@babel/runtime": "^7.14.6",
|
|
12
|
+
"@emotion/css": "^11.7.1",
|
|
13
|
+
"@spark-web/box": "^1.0.0",
|
|
14
|
+
"@spark-web/theme": "^1.0.0",
|
|
15
|
+
"@spark-web/utils": "^1.0.0",
|
|
16
|
+
"react": "^17.0.2"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">= 14.13"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/Strong.tsx
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { css } from '@emotion/css';
|
|
2
|
+
import { useTheme } from '@spark-web/theme';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
export type StrongProps = {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Strong = ({ children }: StrongProps) => {
|
|
10
|
+
const { typography } = useTheme();
|
|
11
|
+
const styles = { fontWeight: typography.fontWeight.strong };
|
|
12
|
+
return <strong className={css(styles)}>{children}</strong>;
|
|
13
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ComponentMeta, ComponentStory } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import type { TextProps } from './Text';
|
|
4
|
+
import { Text } from './Text';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
title: 'Typography / Text',
|
|
8
|
+
component: Text,
|
|
9
|
+
} as ComponentMeta<typeof Text>;
|
|
10
|
+
|
|
11
|
+
const LinkStory: ComponentStory<typeof Text> = (args: TextProps) => (
|
|
12
|
+
<Text {...args} />
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
export const Default = LinkStory.bind({});
|
|
16
|
+
|
|
17
|
+
Default.args = {
|
|
18
|
+
children:
|
|
19
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque rhoncus ex purus, nec rutrum lorem placerat vestibulum. Ut sit amet libero non tellus aliquam pretium nec ac dui. Vivamus erat nibh, placerat vitae nisi eu, aliquet auctor dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;',
|
|
20
|
+
};
|
package/src/Text.tsx
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { css } from '@emotion/css';
|
|
2
|
+
import type { BoxProps } from '@spark-web/box';
|
|
3
|
+
import { Box } from '@spark-web/box';
|
|
4
|
+
import { forwardRefWithAs } from '@spark-web/utils/ts';
|
|
5
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
|
|
8
|
+
import { TextContext, useTextContext } from './context';
|
|
9
|
+
import { useDefaultTextProps } from './defaultTextProps';
|
|
10
|
+
import type { TextOverflowStrategy } from './useOverflowStrategy';
|
|
11
|
+
import { useOverflowStrategy } from './useOverflowStrategy';
|
|
12
|
+
import type { UseTextProps } from './useText';
|
|
13
|
+
import { useText } from './useText';
|
|
14
|
+
|
|
15
|
+
type InlineProps = {
|
|
16
|
+
align?: never;
|
|
17
|
+
/** Display as an inline element. */
|
|
18
|
+
inline?: boolean;
|
|
19
|
+
overflowStrategy?: never;
|
|
20
|
+
};
|
|
21
|
+
type BlockProps = {
|
|
22
|
+
/** The horizontal alignment. */
|
|
23
|
+
align?: 'left' | 'center' | 'right';
|
|
24
|
+
inline?: never;
|
|
25
|
+
/** Manage how text behaves with regard to overflow. */
|
|
26
|
+
overflowStrategy?: TextOverflowStrategy;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type TextProps = Partial<UseTextProps> & {
|
|
30
|
+
/** The text content. */
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
/** An identifier which must be unique in the whole document. */
|
|
33
|
+
id?: BoxProps['id'];
|
|
34
|
+
/** When enabled, numbers will be the same width. Similar to a monospaced font. */
|
|
35
|
+
tabularNumbers?: boolean;
|
|
36
|
+
/** Transform the text casing. */
|
|
37
|
+
transform?: CSSProperties['textTransform'];
|
|
38
|
+
} & (InlineProps | BlockProps);
|
|
39
|
+
|
|
40
|
+
export const Text = forwardRefWithAs<'div', TextProps>(
|
|
41
|
+
(
|
|
42
|
+
{
|
|
43
|
+
// box props
|
|
44
|
+
as,
|
|
45
|
+
children,
|
|
46
|
+
id,
|
|
47
|
+
|
|
48
|
+
//text props
|
|
49
|
+
align,
|
|
50
|
+
baseline: baselineProp,
|
|
51
|
+
inline,
|
|
52
|
+
overflowStrategy,
|
|
53
|
+
size: sizeProp,
|
|
54
|
+
tabularNumbers,
|
|
55
|
+
tone: toneProp,
|
|
56
|
+
transform,
|
|
57
|
+
weight: weightProp,
|
|
58
|
+
},
|
|
59
|
+
forwardedRef
|
|
60
|
+
) => {
|
|
61
|
+
const overflowStyles = useOverflowStrategy(overflowStrategy);
|
|
62
|
+
const textContext = useTextContext();
|
|
63
|
+
const { size, tone, weight } = useDefaultTextProps({
|
|
64
|
+
size: sizeProp ?? textContext?.size,
|
|
65
|
+
tone: toneProp ?? textContext?.tone,
|
|
66
|
+
weight: weightProp ?? textContext?.weight,
|
|
67
|
+
});
|
|
68
|
+
const baseline = !inline && baselineProp;
|
|
69
|
+
const textStyles = useText({ baseline, size, tone, weight });
|
|
70
|
+
const styles = [
|
|
71
|
+
textStyles,
|
|
72
|
+
{
|
|
73
|
+
display: inline ? 'inline' : 'block',
|
|
74
|
+
fontVariantNumeric: tabularNumbers ? 'tabular-nums' : undefined,
|
|
75
|
+
textAlign: align,
|
|
76
|
+
textTransform: transform,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
// early exit for inline variant
|
|
81
|
+
if (inline) {
|
|
82
|
+
return (
|
|
83
|
+
<Box
|
|
84
|
+
as={as ?? 'span'}
|
|
85
|
+
ref={forwardedRef}
|
|
86
|
+
id={id}
|
|
87
|
+
className={css(styles)}
|
|
88
|
+
>
|
|
89
|
+
{children}
|
|
90
|
+
</Box>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// prepare block variant
|
|
95
|
+
const content = overflowStrategy ? (
|
|
96
|
+
<span className={css(overflowStyles)}>{children}</span>
|
|
97
|
+
) : (
|
|
98
|
+
children
|
|
99
|
+
);
|
|
100
|
+
const textContextValue = useMemo(
|
|
101
|
+
() => ({ size, tone, weight }),
|
|
102
|
+
[size, tone, weight]
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<TextContext.Provider value={textContextValue}>
|
|
107
|
+
<Box as={as} ref={forwardedRef} id={id} className={css(styles)}>
|
|
108
|
+
{content}
|
|
109
|
+
</Box>
|
|
110
|
+
</TextContext.Provider>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
);
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { useDefaultTextProps } from './defaultTextProps';
|
|
4
|
+
|
|
5
|
+
type TextContextType = ReturnType<typeof useDefaultTextProps>;
|
|
6
|
+
|
|
7
|
+
export const TextContext = createContext<TextContextType | undefined>(
|
|
8
|
+
undefined
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
export function useTextContext() {
|
|
12
|
+
return useContext(TextContext);
|
|
13
|
+
}
|