@planningcenter/tapestry-react 2.5.1 → 2.6.0-rc.1

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.
@@ -19,6 +19,10 @@ var React = _interopRequireWildcard(require("react"));
19
19
 
20
20
  var _reactDom = require("react-dom");
21
21
 
22
+ var _styles = require("../ThemeProvider/styles");
23
+
24
+ var _react2 = require("@emotion/react");
25
+
22
26
  /** Accepts any additional HTML attributes. */
23
27
  var Portal = /*#__PURE__*/function (_React$Component) {
24
28
  (0, _inheritsLoose2["default"])(Portal, _React$Component);
@@ -31,6 +35,7 @@ var Portal = /*#__PURE__*/function (_React$Component) {
31
35
  }
32
36
 
33
37
  _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
38
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "context", void 0);
34
39
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_portalNode", null);
35
40
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_needsUpdate", false);
36
41
  (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_updated", false);
@@ -125,6 +130,8 @@ var Portal = /*#__PURE__*/function (_React$Component) {
125
130
  _this2._portalNode.setAttribute(key, restProps[key]);
126
131
  });
127
132
 
133
+ this._portalNode.setAttribute((0, _styles.getThemeDataAttribute)(this.context.id), 'true');
134
+
128
135
  if (style) {
129
136
  Object.keys(style).forEach(function (key) {
130
137
  _this2._portalNode.style[key] = style[key];
@@ -163,4 +170,5 @@ exports.Portal = Portal;
163
170
  (0, _defineProperty2["default"])(Portal, "defaultProps", {
164
171
  renderTag: 'div',
165
172
  renderTo: null
166
- });
173
+ });
174
+ (0, _defineProperty2["default"])(Portal, "contextType", _react2.ThemeContext);
@@ -75,6 +75,8 @@ function mergeThemes(a, b) {
75
75
  }
76
76
 
77
77
  function ThemeProvider(_ref) {
78
+ var _ref2;
79
+
78
80
  var _ref$theme = _ref.theme,
79
81
  theme = _ref$theme === void 0 ? emptyTheme : _ref$theme,
80
82
  children = _ref.children;
@@ -87,7 +89,7 @@ function ThemeProvider(_ref) {
87
89
 
88
90
  (0, _react.useLayoutEffect)(function () {
89
91
  var nextTheme = mergeThemes(_defaultTheme["default"], theme);
90
- (0, _styles.setRootStyles)((0, _utils.objectToCSSProperties)('colors', nextTheme.colors));
92
+ (0, _styles.setRootStyles)(nextTheme.id, (0, _utils.objectToCSSProperties)('colors', nextTheme.colors));
91
93
 
92
94
  if (!(0, _utils.shallowEqual)(mergedTheme, nextTheme)) {
93
95
  setMergedTheme(nextTheme);
@@ -97,7 +99,7 @@ function ThemeProvider(_ref) {
97
99
  value: cache
98
100
  }, /*#__PURE__*/_react["default"].createElement(_react2.ThemeProvider, {
99
101
  theme: mergedTheme
100
- }, children));
102
+ }, /*#__PURE__*/_react["default"].createElement("div", (_ref2 = {}, _ref2["" + (0, _styles.getThemeDataAttribute)(mergedTheme.id)] = true, _ref2), children)));
101
103
  }
102
104
 
103
105
  ThemeProvider.cache = cache;
@@ -1,23 +1,33 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
+ exports.getThemeDataAttribute = getThemeDataAttribute;
4
5
  exports.styleReset = exports.defaultColorProperties = exports.setRootStyles = void 0;
5
6
 
6
7
  var _system = require("../system");
7
8
 
8
9
  var _utils = require("../utils");
9
10
 
10
- var getRootStyles = function getRootStyles(styles) {
11
+ function getThemeDataAttribute(themeId) {
12
+ if (themeId) {
13
+ return "data-tapestry-react-theme-provider-" + themeId;
14
+ } else {
15
+ return 'data-tapestry-react-theme-provider';
16
+ }
17
+ }
18
+
19
+ var getRootStyles = function getRootStyles(id, styles) {
11
20
  var styleString = Object.keys(styles).map(function (key) {
12
21
  return key + ": " + styles[key];
13
22
  }).join('; ');
14
- return ":root { " + styleString + " }";
23
+ return "[" + getThemeDataAttribute(id) + "] { " + styleString + " }";
15
24
  };
16
25
 
17
- var setRootStyles = function setRootStyles(styles) {
18
- var styleElement = document.getElementById('tapestry-react-style');
26
+ var setRootStyles = function setRootStyles(themeId, styles) {
27
+ ensureStyleElement(themeId);
28
+ var styleElement = document.getElementById("tapestry-react-style-" + themeId);
19
29
  var sheet = styleElement.sheet;
20
- var styleString = getRootStyles(styles);
30
+ var styleString = getRootStyles(themeId, styles);
21
31
  sheet.deleteRule(0);
22
32
  sheet.insertRule(styleString, 0);
23
33
  };
@@ -25,16 +35,21 @@ var setRootStyles = function setRootStyles(styles) {
25
35
  exports.setRootStyles = setRootStyles;
26
36
  var defaultColorProperties = (0, _utils.objectToCSSProperties)('colors', (0, _system.flattenPalette)(_system.defaultTheme.colors));
27
37
  exports.defaultColorProperties = defaultColorProperties;
28
- var styleReset = ("\n" + getRootStyles(defaultColorProperties) + "\n\n.tapestry-react-reset {\n appearance: none;\n box-sizing: border-box;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n font-weight: 400;\n text-decoration: none;\n flex: 0 0 auto;\n min-width: 0px;\n min-height: 0px;\n padding: 0px;\n margin: 0px;\n border: 0px solid transparent;\n background-color: transparent;\n color: inherit;\n}\n\n.tapestry-react-reset::-moz-focus-inner {\n padding: 0px;\n border: 0px;\n}\n\n.tapestry-react-reset:focus:not(.focus-visible) {\n outline: 0px;\n}\n" // minify string
38
+ var styleReset = ("\n" + getRootStyles(null, defaultColorProperties) + "\n\n.tapestry-react-reset {\n appearance: none;\n box-sizing: border-box;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n font-weight: 400;\n text-decoration: none;\n flex: 0 0 auto;\n min-width: 0px;\n min-height: 0px;\n padding: 0px;\n margin: 0px;\n border: 0px solid transparent;\n background-color: transparent;\n color: inherit;\n}\n\n.tapestry-react-reset::-moz-focus-inner {\n padding: 0px;\n border: 0px;\n}\n\n.tapestry-react-reset:focus:not(.focus-visible) {\n outline: 0px;\n}\n" // minify string
29
39
  ).replace(/\n/g, '').replace(/\s\s+/g, ' '); // we use our own global style implementation in place of Emotion Global
30
40
  // so we can have more control over when styles are injected since multiple
31
41
  // Providers can be used on a page
32
42
 
33
43
  exports.styleReset = styleReset;
34
44
 
35
- if (typeof window !== 'undefined' && !document.getElementById('tapestry-react-style')) {
36
- var styleElement = document.createElement('style');
37
- styleElement.id = 'tapestry-react-style';
38
- styleElement.innerHTML = styleReset;
39
- document.head.insertAdjacentElement('afterbegin', styleElement);
45
+ function ensureStyleElement(themeId) {
46
+ // we use our own global style implementation in place of Emotion Global
47
+ // so we can have more control over when styles are injected since multiple
48
+ // Providers can be used on a page
49
+ if (typeof window !== 'undefined' && !document.getElementById("tapestry-react-style-" + themeId)) {
50
+ var styleElement = document.createElement('style');
51
+ styleElement.id = "tapestry-react-style-" + themeId;
52
+ styleElement.innerHTML = styleReset;
53
+ document.head.insertAdjacentElement('afterbegin', styleElement);
54
+ }
40
55
  }
@@ -23,6 +23,7 @@ var controlStyles = {
23
23
  checkedStroke: 'primary'
24
24
  };
25
25
  var defaultTheme = {
26
+ id: 'default',
26
27
  boxSizes: _boxSizes.boxSizes,
27
28
  colors: _colors.colors,
28
29
  icons: {
@@ -4,6 +4,8 @@ import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
4
4
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
5
5
  import * as React from 'react';
6
6
  import { createPortal } from 'react-dom';
7
+ import { getThemeDataAttribute } from '../ThemeProvider/styles';
8
+ import { ThemeContext } from '@emotion/react';
7
9
 
8
10
  /** Accepts any additional HTML attributes. */
9
11
  var Portal = /*#__PURE__*/function (_React$Component) {
@@ -18,6 +20,8 @@ var Portal = /*#__PURE__*/function (_React$Component) {
18
20
 
19
21
  _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
20
22
 
23
+ _defineProperty(_assertThisInitialized(_this), "context", void 0);
24
+
21
25
  _defineProperty(_assertThisInitialized(_this), "_portalNode", null);
22
26
 
23
27
  _defineProperty(_assertThisInitialized(_this), "_needsUpdate", false);
@@ -116,6 +120,8 @@ var Portal = /*#__PURE__*/function (_React$Component) {
116
120
  _this2._portalNode.setAttribute(key, restProps[key]);
117
121
  });
118
122
 
123
+ this._portalNode.setAttribute(getThemeDataAttribute(this.context.id), 'true');
124
+
119
125
  if (style) {
120
126
  Object.keys(style).forEach(function (key) {
121
127
  _this2._portalNode.style[key] = style[key];
@@ -155,4 +161,6 @@ _defineProperty(Portal, "defaultProps", {
155
161
  renderTo: null
156
162
  });
157
163
 
164
+ _defineProperty(Portal, "contextType", ThemeContext);
165
+
158
166
  export { Portal };
@@ -12,7 +12,7 @@ import { merge } from 'lodash';
12
12
  import defaultTheme from '../system/default-theme';
13
13
  import { flattenPalette } from '../system';
14
14
  import { objectToCSSProperties, shallowEqual } from '../utils';
15
- import { setRootStyles, styleReset } from './styles';
15
+ import { getThemeDataAttribute, setRootStyles, styleReset } from './styles';
16
16
  var STORAGE_KEY = 'tapestry-react-theme';
17
17
  export var cache = createCache({
18
18
  key: 'tapestry-react'
@@ -52,6 +52,8 @@ function mergeThemes(a, b) {
52
52
  }
53
53
 
54
54
  export function ThemeProvider(_ref) {
55
+ var _ref2;
56
+
55
57
  var _ref$theme = _ref.theme,
56
58
  theme = _ref$theme === void 0 ? emptyTheme : _ref$theme,
57
59
  children = _ref.children;
@@ -64,7 +66,7 @@ export function ThemeProvider(_ref) {
64
66
 
65
67
  useLayoutEffect(function () {
66
68
  var nextTheme = mergeThemes(defaultTheme, theme);
67
- setRootStyles(objectToCSSProperties('colors', nextTheme.colors));
69
+ setRootStyles(nextTheme.id, objectToCSSProperties('colors', nextTheme.colors));
68
70
 
69
71
  if (!shallowEqual(mergedTheme, nextTheme)) {
70
72
  setMergedTheme(nextTheme);
@@ -74,7 +76,7 @@ export function ThemeProvider(_ref) {
74
76
  value: cache
75
77
  }, /*#__PURE__*/React.createElement(EmotionThemeProvider, {
76
78
  theme: mergedTheme
77
- }, children));
79
+ }, /*#__PURE__*/React.createElement("div", (_ref2 = {}, _ref2["" + getThemeDataAttribute(mergedTheme.id)] = true, _ref2), children)));
78
80
  }
79
81
  ThemeProvider.cache = cache;
80
82
  ThemeProvider.setRootStyles = setRootStyles;
@@ -1,29 +1,42 @@
1
1
  import { defaultTheme, flattenPalette } from '../system';
2
2
  import { objectToCSSProperties } from '../utils';
3
+ export function getThemeDataAttribute(themeId) {
4
+ if (themeId) {
5
+ return "data-tapestry-react-theme-provider-" + themeId;
6
+ } else {
7
+ return 'data-tapestry-react-theme-provider';
8
+ }
9
+ }
3
10
 
4
- var getRootStyles = function getRootStyles(styles) {
11
+ var getRootStyles = function getRootStyles(id, styles) {
5
12
  var styleString = Object.keys(styles).map(function (key) {
6
13
  return key + ": " + styles[key];
7
14
  }).join('; ');
8
- return ":root { " + styleString + " }";
15
+ return "[" + getThemeDataAttribute(id) + "] { " + styleString + " }";
9
16
  };
10
17
 
11
- export var setRootStyles = function setRootStyles(styles) {
12
- var styleElement = document.getElementById('tapestry-react-style');
18
+ export var setRootStyles = function setRootStyles(themeId, styles) {
19
+ ensureStyleElement(themeId);
20
+ var styleElement = document.getElementById("tapestry-react-style-" + themeId);
13
21
  var sheet = styleElement.sheet;
14
- var styleString = getRootStyles(styles);
22
+ var styleString = getRootStyles(themeId, styles);
15
23
  sheet.deleteRule(0);
16
24
  sheet.insertRule(styleString, 0);
17
25
  };
18
26
  export var defaultColorProperties = objectToCSSProperties('colors', flattenPalette(defaultTheme.colors));
19
- export var styleReset = ("\n" + getRootStyles(defaultColorProperties) + "\n\n.tapestry-react-reset {\n appearance: none;\n box-sizing: border-box;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n font-weight: 400;\n text-decoration: none;\n flex: 0 0 auto;\n min-width: 0px;\n min-height: 0px;\n padding: 0px;\n margin: 0px;\n border: 0px solid transparent;\n background-color: transparent;\n color: inherit;\n}\n\n.tapestry-react-reset::-moz-focus-inner {\n padding: 0px;\n border: 0px;\n}\n\n.tapestry-react-reset:focus:not(.focus-visible) {\n outline: 0px;\n}\n" // minify string
27
+ export var styleReset = ("\n" + getRootStyles(null, defaultColorProperties) + "\n\n.tapestry-react-reset {\n appearance: none;\n box-sizing: border-box;\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n font-weight: 400;\n text-decoration: none;\n flex: 0 0 auto;\n min-width: 0px;\n min-height: 0px;\n padding: 0px;\n margin: 0px;\n border: 0px solid transparent;\n background-color: transparent;\n color: inherit;\n}\n\n.tapestry-react-reset::-moz-focus-inner {\n padding: 0px;\n border: 0px;\n}\n\n.tapestry-react-reset:focus:not(.focus-visible) {\n outline: 0px;\n}\n" // minify string
20
28
  ).replace(/\n/g, '').replace(/\s\s+/g, ' '); // we use our own global style implementation in place of Emotion Global
21
29
  // so we can have more control over when styles are injected since multiple
22
30
  // Providers can be used on a page
23
31
 
24
- if (typeof window !== 'undefined' && !document.getElementById('tapestry-react-style')) {
25
- var styleElement = document.createElement('style');
26
- styleElement.id = 'tapestry-react-style';
27
- styleElement.innerHTML = styleReset;
28
- document.head.insertAdjacentElement('afterbegin', styleElement);
32
+ function ensureStyleElement(themeId) {
33
+ // we use our own global style implementation in place of Emotion Global
34
+ // so we can have more control over when styles are injected since multiple
35
+ // Providers can be used on a page
36
+ if (typeof window !== 'undefined' && !document.getElementById("tapestry-react-style-" + themeId)) {
37
+ var styleElement = document.createElement('style');
38
+ styleElement.id = "tapestry-react-style-" + themeId;
39
+ styleElement.innerHTML = styleReset;
40
+ document.head.insertAdjacentElement('afterbegin', styleElement);
41
+ }
29
42
  }
@@ -1,5 +1,5 @@
1
- import * as general from "@planningcenter/icons/paths/general";
2
- import * as tapestry from "@planningcenter/icons/paths/tapestry";
1
+ import * as general from '@planningcenter/icons/paths/general';
2
+ import * as tapestry from '@planningcenter/icons/paths/tapestry';
3
3
  import { boxSizes } from './box-sizes';
4
4
  import { buttonThemes } from './button-themes';
5
5
  import { colors } from './colors';
@@ -11,6 +11,7 @@ var controlStyles = {
11
11
  checkedStroke: 'primary'
12
12
  };
13
13
  var defaultTheme = {
14
+ id: 'default',
14
15
  boxSizes: boxSizes,
15
16
  colors: colors,
16
17
  icons: {
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { Theme } from '../index';
2
3
  export declare type PortalProps = {
3
4
  children: any;
4
5
  /** Styles to apply to the portal root element. */
@@ -18,6 +19,8 @@ declare class Portal extends React.Component<PortalProps> {
18
19
  renderTag: string;
19
20
  renderTo: any;
20
21
  };
22
+ static contextType: import("react").Context<object>;
23
+ context: React.ContextType<React.Context<Theme>>;
21
24
  _portalNode: HTMLElement;
22
25
  _needsUpdate: boolean;
23
26
  _updated: boolean;
@@ -13,7 +13,7 @@ export declare function ThemeProvider({ theme, children, }: {
13
13
  }): JSX.Element;
14
14
  export declare namespace ThemeProvider {
15
15
  var cache: import("@emotion/utils").EmotionCache;
16
- var setRootStyles: (styles: any) => void;
16
+ var setRootStyles: (themeId: any, styles: any) => void;
17
17
  var styleReset: string;
18
18
  var themeInitializerScript: string;
19
19
  var themeStorage: {
@@ -1,3 +1,4 @@
1
- export declare const setRootStyles: (styles: any) => void;
1
+ export declare function getThemeDataAttribute(themeId: any): string;
2
+ export declare const setRootStyles: (themeId: any, styles: any) => void;
2
3
  export declare const defaultColorProperties: any;
3
4
  export declare const styleReset: string;
@@ -184,6 +184,7 @@ export interface ButtonTheme {
184
184
  }
185
185
 
186
186
  export interface Theme {
187
+ id?: string
187
188
  boxSizes?: Record<keyof BoxSizes, BoxProps>
188
189
  breakpoints?: Partial<Breakpoints>
189
190
  button?: { themes?: { [key: string]: ButtonTheme } }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planningcenter/tapestry-react",
3
- "version": "2.5.1",
3
+ "version": "2.6.0-rc.1",
4
4
  "description": "A collection of flexible React components to help you build resilient, accessible user interfaces quickly and effectively.",
5
5
  "author": "Front End Systems Engineering <frontend@pco.bz>",
6
6
  "main": "dist/cjs/index.js",
@@ -1,5 +1,8 @@
1
1
  import * as React from 'react'
2
2
  import { createPortal } from 'react-dom'
3
+ import { getThemeDataAttribute } from '../ThemeProvider/styles'
4
+ import { ThemeContext } from '@emotion/react'
5
+ import { Theme } from '../index'
3
6
 
4
7
  export type PortalProps = {
5
8
  children: any
@@ -27,6 +30,9 @@ class Portal extends React.Component<PortalProps> {
27
30
  renderTo: null,
28
31
  }
29
32
 
33
+ static contextType = ThemeContext
34
+ context: React.ContextType<React.Context<Theme>>
35
+
30
36
  _portalNode: HTMLElement = null
31
37
  _needsUpdate = false
32
38
  _updated = false
@@ -105,6 +111,11 @@ class Portal extends React.Component<PortalProps> {
105
111
  Object.keys(restProps).forEach((key) => {
106
112
  this._portalNode.setAttribute(key, restProps[key])
107
113
  })
114
+ this._portalNode.setAttribute(
115
+ getThemeDataAttribute(this.context.id),
116
+ 'true'
117
+ )
118
+
108
119
  if (style) {
109
120
  Object.keys(style).forEach((key) => {
110
121
  this._portalNode.style[key] = style[key]
@@ -8,7 +8,7 @@ import defaultTheme from '../system/default-theme'
8
8
  import { flattenPalette } from '../system'
9
9
  import { Theme } from '../index'
10
10
  import { objectToCSSProperties, shallowEqual } from '../utils'
11
- import { setRootStyles, styleReset } from './styles'
11
+ import { getThemeDataAttribute, setRootStyles, styleReset } from './styles'
12
12
 
13
13
  const STORAGE_KEY = 'tapestry-react-theme'
14
14
 
@@ -65,7 +65,10 @@ export function ThemeProvider({
65
65
  )
66
66
  useLayoutEffect(() => {
67
67
  const nextTheme = mergeThemes(defaultTheme, theme)
68
- setRootStyles(objectToCSSProperties('colors', nextTheme.colors))
68
+ setRootStyles(
69
+ nextTheme.id,
70
+ objectToCSSProperties('colors', nextTheme.colors)
71
+ )
69
72
  if (!shallowEqual(mergedTheme, nextTheme)) {
70
73
  setMergedTheme(nextTheme)
71
74
  }
@@ -73,7 +76,9 @@ export function ThemeProvider({
73
76
  return (
74
77
  <CacheProvider value={cache}>
75
78
  <EmotionThemeProvider theme={mergedTheme}>
76
- {children}
79
+ <div {...{ [`${getThemeDataAttribute(mergedTheme.id)}`]: true }}>
80
+ {children}
81
+ </div>
77
82
  </EmotionThemeProvider>
78
83
  </CacheProvider>
79
84
  )
@@ -1,17 +1,30 @@
1
1
  import { defaultTheme, flattenPalette } from '../system'
2
2
  import { objectToCSSProperties } from '../utils'
3
3
 
4
- const getRootStyles = (styles) => {
4
+ export function getThemeDataAttribute(themeId) {
5
+ if (themeId) {
6
+ return `data-tapestry-react-theme-provider-${themeId}`
7
+ } else {
8
+ return 'data-tapestry-react-theme-provider'
9
+ }
10
+ }
11
+
12
+ const getRootStyles = (id, styles) => {
5
13
  const styleString = Object.keys(styles)
6
14
  .map((key) => `${key}: ${styles[key]}`)
7
15
  .join('; ')
8
- return `:root { ${styleString} }`
16
+
17
+ return `[${getThemeDataAttribute(id)}] { ${styleString} }`
9
18
  }
10
19
 
11
- export const setRootStyles = (styles) => {
12
- const styleElement = <HTMLStyleElement>document.getElementById('tapestry-react-style')
20
+ export const setRootStyles = (themeId, styles) => {
21
+ ensureStyleElement(themeId)
22
+ const styleElement = <HTMLStyleElement>(
23
+ document.getElementById(`tapestry-react-style-${themeId}`)
24
+ )
25
+
13
26
  const sheet = <CSSStyleSheet>styleElement.sheet
14
- const styleString = getRootStyles(styles)
27
+ const styleString = getRootStyles(themeId, styles)
15
28
  sheet.deleteRule(0)
16
29
  sheet.insertRule(styleString, 0)
17
30
  }
@@ -22,7 +35,7 @@ export const defaultColorProperties = objectToCSSProperties(
22
35
  )
23
36
 
24
37
  export const styleReset = `
25
- ${getRootStyles(defaultColorProperties)}
38
+ ${getRootStyles(null, defaultColorProperties)}
26
39
 
27
40
  .tapestry-react-reset {
28
41
  appearance: none;
@@ -56,9 +69,17 @@ ${getRootStyles(defaultColorProperties)}
56
69
  // we use our own global style implementation in place of Emotion Global
57
70
  // so we can have more control over when styles are injected since multiple
58
71
  // Providers can be used on a page
59
- if (typeof window !== 'undefined' && !document.getElementById('tapestry-react-style')) {
60
- const styleElement = document.createElement('style')
61
- styleElement.id = 'tapestry-react-style'
62
- styleElement.innerHTML = styleReset
63
- document.head.insertAdjacentElement('afterbegin', styleElement)
72
+ function ensureStyleElement(themeId) {
73
+ // we use our own global style implementation in place of Emotion Global
74
+ // so we can have more control over when styles are injected since multiple
75
+ // Providers can be used on a page
76
+ if (
77
+ typeof window !== 'undefined' &&
78
+ !document.getElementById(`tapestry-react-style-${themeId}`)
79
+ ) {
80
+ const styleElement = document.createElement('style')
81
+ styleElement.id = `tapestry-react-style-${themeId}`
82
+ styleElement.innerHTML = styleReset
83
+ document.head.insertAdjacentElement('afterbegin', styleElement)
84
+ }
64
85
  }
package/src/index.d.ts CHANGED
@@ -184,6 +184,7 @@ export interface ButtonTheme {
184
184
  }
185
185
 
186
186
  export interface Theme {
187
+ id?: string
187
188
  boxSizes?: Record<keyof BoxSizes, BoxProps>
188
189
  breakpoints?: Partial<Breakpoints>
189
190
  button?: { themes?: { [key: string]: ButtonTheme } }
@@ -1,5 +1,5 @@
1
- import * as general from "@planningcenter/icons/paths/general"
2
- import * as tapestry from "@planningcenter/icons/paths/tapestry"
1
+ import * as general from '@planningcenter/icons/paths/general'
2
+ import * as tapestry from '@planningcenter/icons/paths/tapestry'
3
3
 
4
4
  import { Theme } from '../index'
5
5
 
@@ -16,6 +16,7 @@ const controlStyles = {
16
16
  }
17
17
 
18
18
  const defaultTheme: Theme = {
19
+ id: 'default',
19
20
  boxSizes,
20
21
  colors,
21
22
  icons: {