@khanacademy/wonder-blocks-core 0.0.0-PR2089-20231019161345

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 (80) hide show
  1. package/CHANGELOG.md +245 -0
  2. package/dist/components/id-provider.d.ts +58 -0
  3. package/dist/components/render-state-context.d.ts +23 -0
  4. package/dist/components/render-state-root.d.ts +10 -0
  5. package/dist/components/text.d.ts +66 -0
  6. package/dist/components/unique-id-provider.d.ts +69 -0
  7. package/dist/components/view.d.ts +37 -0
  8. package/dist/components/with-ssr-placeholder.d.ts +63 -0
  9. package/dist/es/index.js +479 -0
  10. package/dist/hooks/use-force-update.d.ts +13 -0
  11. package/dist/hooks/use-is-mounted.d.ts +18 -0
  12. package/dist/hooks/use-latest-ref.d.ts +13 -0
  13. package/dist/hooks/use-on-mount-effect.d.ts +29 -0
  14. package/dist/hooks/use-online.d.ts +9 -0
  15. package/dist/hooks/use-pre-hydration-effect.d.ts +20 -0
  16. package/dist/hooks/use-render-state.d.ts +2 -0
  17. package/dist/hooks/use-unique-id.d.ts +18 -0
  18. package/dist/index.d.ts +19 -0
  19. package/dist/index.js +519 -0
  20. package/dist/util/add-style.d.ts +185 -0
  21. package/dist/util/add-styles.typestest.d.ts +1 -0
  22. package/dist/util/aria-types.d.ts +187 -0
  23. package/dist/util/server.d.ts +14 -0
  24. package/dist/util/ssr-id-factory.d.ts +3 -0
  25. package/dist/util/types.d.ts +87 -0
  26. package/dist/util/types.propsfor.d.ts +9 -0
  27. package/dist/util/unique-id-factory.d.ts +37 -0
  28. package/dist/util/util.d.ts +8 -0
  29. package/package.json +30 -0
  30. package/src/components/__tests__/__snapshots__/view.test.js.snap +133 -0
  31. package/src/components/__tests__/id-provider.test.tsx +48 -0
  32. package/src/components/__tests__/render-state-root.test.tsx +86 -0
  33. package/src/components/__tests__/text.test.tsx +17 -0
  34. package/src/components/__tests__/unique-id-provider.test.tsx +188 -0
  35. package/src/components/__tests__/view.test.js +60 -0
  36. package/src/components/__tests__/with-ssr-placeholder.test.tsx +259 -0
  37. package/src/components/id-provider.tsx +87 -0
  38. package/src/components/render-state-context.ts +29 -0
  39. package/src/components/render-state-root.tsx +47 -0
  40. package/src/components/text.tsx +68 -0
  41. package/src/components/unique-id-provider.tsx +111 -0
  42. package/src/components/view.tsx +101 -0
  43. package/src/components/with-ssr-placeholder.tsx +174 -0
  44. package/src/hooks/__tests__/use-force-update.test.tsx +121 -0
  45. package/src/hooks/__tests__/use-is-mounted.test.tsx +87 -0
  46. package/src/hooks/__tests__/use-latest-ref.test.ts +40 -0
  47. package/src/hooks/__tests__/use-latest-ref.typestest.ts +21 -0
  48. package/src/hooks/__tests__/use-on-mount-effect.test.ts +30 -0
  49. package/src/hooks/__tests__/use-online.test.tsx +69 -0
  50. package/src/hooks/__tests__/use-pre-hydration-effect.test.tsx +88 -0
  51. package/src/hooks/__tests__/use-render-state.test.tsx +56 -0
  52. package/src/hooks/__tests__/use-unique-id.test.tsx +256 -0
  53. package/src/hooks/use-force-update.ts +28 -0
  54. package/src/hooks/use-is-mounted.ts +32 -0
  55. package/src/hooks/use-latest-ref.ts +17 -0
  56. package/src/hooks/use-on-mount-effect.ts +34 -0
  57. package/src/hooks/use-online.ts +28 -0
  58. package/src/hooks/use-pre-hydration-effect.ts +47 -0
  59. package/src/hooks/use-render-state.ts +10 -0
  60. package/src/hooks/use-unique-id.ts +68 -0
  61. package/src/index.ts +29 -0
  62. package/src/util/__tests__/__snapshots__/unique-id-factory.test.ts.snap +9 -0
  63. package/src/util/__tests__/add-style.test.tsx +111 -0
  64. package/src/util/__tests__/server.test.ts +36 -0
  65. package/src/util/__tests__/ssr-id-factory.test.ts +13 -0
  66. package/src/util/__tests__/unique-id-factory.test.ts +164 -0
  67. package/src/util/add-style.js.flow +13 -0
  68. package/src/util/add-style.tsx +254 -0
  69. package/src/util/add-styles.typestest.tsx +21 -0
  70. package/src/util/aria-types.ts +304 -0
  71. package/src/util/server.md +24 -0
  72. package/src/util/server.ts +18 -0
  73. package/src/util/ssr-id-factory.ts +21 -0
  74. package/src/util/types.propsfor.js.flow +9 -0
  75. package/src/util/types.propsfor.ts +14 -0
  76. package/src/util/types.ts +112 -0
  77. package/src/util/unique-id-factory.ts +62 -0
  78. package/src/util/util.ts +91 -0
  79. package/tsconfig-build.json +9 -0
  80. package/tsconfig-build.tsbuildinfo +1 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,245 @@
1
+ # @khanacademy/wonder-blocks-core
2
+
3
+ ## 0.0.0-PR2089-20231019161345
4
+
5
+ ### Minor Changes
6
+
7
+ - ab3f7875: Make useOnMountEffect accept functions with void return types
8
+
9
+ ## 6.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 4b97b9a2: Remove deps argument from `usePreHydrationEffect`
14
+
15
+ ## 6.1.1
16
+
17
+ ### Patch Changes
18
+
19
+ - 2871f0a9: Add new usePreHydrationEffect hook to module exports
20
+
21
+ ## 6.1.0
22
+
23
+ ### Minor Changes
24
+
25
+ - efb59c29: Add `usePreHydrationEffect`
26
+
27
+ ### Patch Changes
28
+
29
+ - 8bc40ed2: Change the return type of `useLatestRef` from `RefObject<T>` to
30
+ `{readonly current: T}`, so the `current` property is not nullable.
31
+
32
+ This fixes a bug introduced by the migration to TypeScript.
33
+
34
+ ## 6.0.2
35
+
36
+ ### Patch Changes
37
+
38
+ - f19da46e: Allow 'title' on View and typography components
39
+
40
+ ## 6.0.1
41
+
42
+ ### Patch Changes
43
+
44
+ - 1920feb8: `RenderStateRoot` now wraps children in a React fragment
45
+
46
+ ## 6.0.0
47
+
48
+ ### Major Changes
49
+
50
+ - 674a1e5c: POJOs have been replace with TS enums
51
+
52
+ ### Patch Changes
53
+
54
+ - 674a1e5c: We're no longer building flow types
55
+
56
+ ## 5.4.0
57
+
58
+ ### Minor Changes
59
+
60
+ - 1344436f: Add `PropsFor` type to simplify `JSX.LibraryManagedAttributes` usage
61
+
62
+ ## 5.3.1
63
+
64
+ ### Patch Changes
65
+
66
+ - 9f3752d4: Used named functions in componenets with forwarded refs
67
+
68
+ ## 5.3.0
69
+
70
+ ### Minor Changes
71
+
72
+ - c37b99aa: Forward refs for Text and Title
73
+ - c4cef3e6: Added ref forwarding to View
74
+
75
+ ## 5.2.3
76
+
77
+ ### Patch Changes
78
+
79
+ - d4c412b5: Update useForceUpdate to ensure consuming hooks properly refresh
80
+
81
+ ## 5.2.2
82
+
83
+ ### Patch Changes
84
+
85
+ - 64a188e3: Fix useForceUpdate so that regardless of how many times it is called before a new render, it will always cause a new render
86
+
87
+ ## 5.2.1
88
+
89
+ ### Patch Changes
90
+
91
+ - 5a1ea891: Make sure that React contexts are named
92
+ - df9a10aa: Update state and props to be readonly in components using getDerivedStateFromProps()
93
+
94
+ ## 5.2.0
95
+
96
+ ### Minor Changes
97
+
98
+ - fa70c895: Add 'lang', 'className' and 'htmlFor' properties to Text and View
99
+
100
+ ### Patch Changes
101
+
102
+ - 19ab0408: Update flowgen to convert React.ForwardRefExoticComponent<> and React.FowardedRef<> properly
103
+ - fa70c895: Remove all TypeScript error suppressions on JSX attributes
104
+
105
+ ## 5.1.0
106
+
107
+ ### Minor Changes
108
+
109
+ - 3c400719: Add useLatestRef hook to wonder-blocks-core
110
+
111
+ ### Patch Changes
112
+
113
+ - a6164ed0: Don't use React.FC<> for functional components
114
+
115
+ ## 5.0.4
116
+
117
+ ### Patch Changes
118
+
119
+ - c20f48f3: Don't transpile classes when building bundles
120
+
121
+ ## 5.0.3
122
+
123
+ ### Patch Changes
124
+
125
+ - b281e2eb: Fix generate Flow types for real
126
+
127
+ ## 5.0.2
128
+
129
+ ### Patch Changes
130
+
131
+ - 21ce20c7: Fix issues with generate flow types in wonder-blocks-core
132
+
133
+ ## 5.0.1
134
+
135
+ ### Patch Changes
136
+
137
+ - ccb6fe00: Miscellaneous TS type fixes
138
+ - d4c2b18c: Fix a variety of issues with Flow types generated by flowgen
139
+
140
+ ## 5.0.0
141
+
142
+ ### Major Changes
143
+
144
+ - 1ca4d7e3: Fix minor issue with generate Flow types (this is a major bump b/c I forgot to do one after doing the TS conversion)
145
+
146
+ ## 4.9.1
147
+
148
+ ### Patch Changes
149
+
150
+ - b5ba5568: Ensure that flow lib defs use React.ElementConfig<> isntead of JSX.LibraryManagedAttributes<>
151
+
152
+ ## 4.9.0
153
+
154
+ ### Minor Changes
155
+
156
+ - 779b031d: Update AriaProps to use React's AriaAttributes and AriaRole types
157
+
158
+ ## 4.8.0
159
+
160
+ ### Minor Changes
161
+
162
+ - 873f4a14: Update aphrodite lib def and StyleType
163
+
164
+ ### Patch Changes
165
+
166
+ - d816af08: Update build and test configs use TypeScript
167
+ - 3891f544: Update babel config to include plugins that Storybook needed
168
+ - 0d28bb1c: Configured TypeScript
169
+ - 3d05f764: Fix HOCs and other type errors
170
+ - c2ec4902: Update eslint configuration, fix lint
171
+ - 2983c05b: Include 'types' field in package.json
172
+ - 77ff6a66: Generate Flow types from TypeScript types
173
+ - ec8d4b7f: Fix miscellaneous TypeScript errors
174
+
175
+ ## 4.7.0
176
+
177
+ ### Minor Changes
178
+
179
+ - 91cb727c: Convert enums to POJOs
180
+
181
+ ### Patch Changes
182
+
183
+ - 91cb727c: Remove file extensions from imports
184
+
185
+ ## 4.6.2
186
+
187
+ ### Patch Changes
188
+
189
+ - 496119f2: Cleanup WB interdependencies
190
+
191
+ ## 4.6.1
192
+
193
+ ## 4.6.0
194
+
195
+ ### Minor Changes
196
+
197
+ - b561425a: Add useIsMounted() hook
198
+ - a566e232: Add useOnMountEffect hook
199
+ - d2b21a6e: Export useOnMountEffect hook
200
+
201
+ ## 4.5.0
202
+
203
+ ### Minor Changes
204
+
205
+ - 175a2dd2: Add 'useRenderState' hook
206
+
207
+ ## 4.4.0
208
+
209
+ ### Minor Changes
210
+
211
+ - 6ee20af9: Add `useOnline` hook to encapsulate navigator.onLine and the offline/online events
212
+
213
+ ## 4.3.2
214
+
215
+ ### Patch Changes
216
+
217
+ - 5f4a4297: Make dependency on `flow-enums-runtime` explicit
218
+ - 2b96fd59: Change flow-enums-runtime to be peer dependencies
219
+
220
+ ## 4.3.1
221
+
222
+ ## 4.3.0
223
+
224
+ ### Minor Changes
225
+
226
+ - 246a921d: NEW: `useForceUpdate` hook. This should rarely be used and likely only ever from other hooks.
227
+
228
+ ## 4.2.1
229
+
230
+ ## 4.2.0
231
+
232
+ ### Minor Changes
233
+
234
+ - 0aed8723: Adds `throwIfNested` required prop to `RenderStateRoot`.
235
+
236
+ ## 4.1.0
237
+
238
+ ### Minor Changes
239
+
240
+ - 45588e5f: Fix an issue with `useUniqueIdWithMock`/`useUniqueIdWithoutMock`
241
+ rerender more than was needed. The fix introduces `<RenderStateRoot>`
242
+ which must be an ancestor to all components uses these hooks.
243
+ - 875b7893: Nesting of `RenderStateRoot`s inside each other can result in extra renders
244
+ and potentially incorrect behavior. `RenderStateRoot` now throws if it
245
+ appears as a descendent of another `RenderStateRoot`.
@@ -0,0 +1,58 @@
1
+ import * as React from "react";
2
+ import type { IIdentifierFactory } from "../util/types";
3
+ type Props = {
4
+ /**
5
+ * Use the children-as-function pattern to pass a uniqueId string for
6
+ * use anywhere within children. This provides a way of adding a unique identifier
7
+ * to a given component for a11y purposes.
8
+ */
9
+ children: (uniqueId: string) => React.ReactNode;
10
+ /**
11
+ * Scope for the unique identifier
12
+ */
13
+ scope: string;
14
+ /**
15
+ * An optional id parameter for the title. If one is
16
+ * not provided, a unique id will be generated.
17
+ */
18
+ id?: string;
19
+ /**
20
+ * Test ID used for e2e testing.
21
+ */
22
+ testId?: string;
23
+ };
24
+ /**
25
+ * This is a wrapper that returns an identifier. If the `id` prop is set, the
26
+ * component will return the same id to be consumed by its children. Otherwise,
27
+ * a unique id will be provided. This is beneficial for accessibility purposes,
28
+ * among other things.
29
+ *
30
+ * The main difference with `UniqueIDProvider` is that `IDProvider` has a single
31
+ * responsibility, to return an identifier that can by used by the children that
32
+ * are rendered internally.
33
+ *
34
+ * This way, the wrapped component will receive this custom ID and will use it
35
+ * to connect different elements.
36
+ *
37
+ * e.g. It uses the same generated id to connect a Dialog with its main title,
38
+ * or form label with the associated input element, etc.
39
+ *
40
+ * ## Usage
41
+ *
42
+ * ```jsx
43
+ * import {IDProvider} from "@khanacademy/wonder-blocks-core";
44
+ *
45
+ * <IDProvider scope="field">
46
+ * {(uniqueId) => (
47
+ * Unique ID: {uniqueId}
48
+ * )}
49
+ * </IDProvider>
50
+ * ```
51
+ *
52
+ */
53
+ export default class IDProvider extends React.Component<Props> {
54
+ static defaultId: string;
55
+ renderChildren(ids?: IIdentifierFactory): React.ReactNode;
56
+ render(): React.ReactNode;
57
+ }
58
+ export {};
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ export declare enum RenderState {
3
+ Root = "root",
4
+ Initial = "initial",
5
+ Standard = "standard"
6
+ }
7
+ /**
8
+ * This is the context that tracks who is doing what in our SSR component tree.
9
+ *
10
+ * root:
11
+ * no one has instigated an initial SSR render so the component that sees
12
+ * this "root" state is responsible for controlling initial versus standard
13
+ * rendering semantics
14
+ *
15
+ * initial:
16
+ * this means the SSR render has started, and all SSR components should act
17
+ * as though they are on the server
18
+ *
19
+ * standard:
20
+ * means that we're all now doing non-SSR rendering
21
+ */
22
+ declare const RenderStateContext: React.Context<RenderState>;
23
+ export { RenderStateContext };
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ type Props = {
3
+ children: React.ReactNode;
4
+ /**
5
+ * Whether the component should throw when nested. Defaults to `true`.
6
+ */
7
+ throwIfNested?: boolean;
8
+ };
9
+ declare const RenderStateRoot: ({ children, throwIfNested, }: Props) => React.ReactElement;
10
+ export { RenderStateRoot };
@@ -0,0 +1,66 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Text is a building block for constructing other components. `Text` roughly
4
+ * maps to `span`. You can override which tag is used to render the component
5
+ * (for semantic purposes) by specifying the `tag` prop.
6
+ *
7
+ * These components can take styles (via the `style` prop) in a variety of
8
+ * manners:
9
+ *
10
+ * - An inline style object
11
+ * - An `aphrodite` StyleSheet style
12
+ * - An array combining the above
13
+ */
14
+ declare const Text: React.ForwardRefExoticComponent<{
15
+ children?: React.ReactNode;
16
+ style?: import("../util/types").StyleType;
17
+ testId?: string | undefined;
18
+ lang?: string | undefined;
19
+ className?: string | undefined;
20
+ htmlFor?: string | undefined;
21
+ tabIndex?: number | undefined;
22
+ id?: string | undefined;
23
+ title?: string | undefined;
24
+ "data-modal-launcher-portal"?: boolean | undefined;
25
+ "data-placement"?: string | undefined;
26
+ } & Readonly<import("../util/aria-types").AriaAttributes> & Readonly<{
27
+ role?: import("../util/aria-types").AriaRole | undefined;
28
+ }> & {
29
+ onMouseDown?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
30
+ onMouseUp?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
31
+ onMouseMove?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
32
+ onClick?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
33
+ onDoubleClick?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
34
+ onMouseEnter?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
35
+ onMouseLeave?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
36
+ onMouseOut?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
37
+ onMouseOver?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
38
+ onDrag?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
39
+ onDragEnd?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
40
+ onDragEnter?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
41
+ onDragExit?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
42
+ onDragLeave?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
43
+ onDragOver?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
44
+ onDragStart?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
45
+ onDrop?: ((e: React.MouseEvent<Element, MouseEvent>) => unknown) | undefined;
46
+ } & {
47
+ onKeyDown?: ((e: React.KeyboardEvent<Element>) => unknown) | undefined;
48
+ onKeyPress?: ((e: React.KeyboardEvent<Element>) => unknown) | undefined;
49
+ onKeyUp?: ((e: React.KeyboardEvent<Element>) => unknown) | undefined;
50
+ } & {
51
+ onChange?: ((e: React.ChangeEvent<HTMLInputElement>) => unknown) | undefined;
52
+ onInput?: ((e: React.ChangeEvent<HTMLInputElement>) => unknown) | undefined;
53
+ onInvalid?: ((e: React.ChangeEvent<HTMLInputElement>) => unknown) | undefined;
54
+ onSubmit?: ((e: React.ChangeEvent<HTMLInputElement>) => unknown) | undefined;
55
+ } & {
56
+ onTouchCancel?: ((e: React.TouchEvent<Element>) => unknown) | undefined;
57
+ onTouchEnd?: ((e: React.TouchEvent<Element>) => unknown) | undefined;
58
+ onTouchMove?: ((e: React.TouchEvent<Element>) => unknown) | undefined;
59
+ onTouchStart?: ((e: React.TouchEvent<Element>) => unknown) | undefined;
60
+ } & {
61
+ onFocus?: ((e: React.FocusEvent<Element, Element>) => unknown) | undefined;
62
+ onBlur?: ((e: React.FocusEvent<Element, Element>) => unknown) | undefined;
63
+ } & {
64
+ tag?: string | undefined;
65
+ } & React.RefAttributes<unknown>>;
66
+ export default Text;
@@ -0,0 +1,69 @@
1
+ import * as React from "react";
2
+ import type { IIdentifierFactory } from "../util/types";
3
+ type Props = {
4
+ /**
5
+ * A render prop that takes an instance of IIdentifierFactory and returns
6
+ * the content to be rendered.
7
+ *
8
+ * If mockOnFirstRender is false, this is only called after
9
+ * the initial render has occurred -- it will be blank for the
10
+ * the first render -- and will always be called with the same
11
+ * IIdentifierFactory instance.
12
+ *
13
+ * If mockOnFirstRender is true, this is called once with
14
+ * a mock IIdentifierFactory for the initial render, and then a unique ID
15
+ * factory thereafter.
16
+ *
17
+ * Full type with `IIdentifierFactory` definition inlined is:
18
+ *
19
+ * `{get(id: string): string} => React.Node`
20
+ */
21
+ children: (arg1: IIdentifierFactory) => React.ReactNode;
22
+ /**
23
+ * If mockOnFirstRender is false, children is only called
24
+ * after the initial render has occurred.
25
+ * If mockOnFirstRender is true, children is called once with
26
+ * a mock IIdentifierFactory for the initial render, and then a unique ID
27
+ * factory thereafter.
28
+ */
29
+ mockOnFirstRender: boolean;
30
+ /**
31
+ * If this prop is specified, any identifiers provided will contain the
32
+ * given scope. This can be useful for making easily readable identifiers.
33
+ */
34
+ readonly scope?: string;
35
+ };
36
+ /**
37
+ * The `UniqueIDProvider` component is how Wonder Blocks components obtain
38
+ * unique identifiers. This component ensures that server-side rendering and
39
+ * initial client rendering match while allowing the provision of unique
40
+ * identifiers for the client.
41
+ *
42
+ * In all but the first render, the children are rendered with the same
43
+ * `IIdentifierFactory` instance, ensuring that the same calls will return the
44
+ * same identifiers.
45
+ *
46
+ * The `get` method of the identifier factory ensures that the same identifier
47
+ * is returned for like requests, but also that all identifiers provided are
48
+ * unique. Therefore, `get("test")` will always equal `get("test")`, and
49
+ * `get("test2")` will always equal `get("test2")`, but `get("test")` will
50
+ * never equal `get("test2")`.
51
+ *
52
+ * ## Usage
53
+ *
54
+ * ```jsx
55
+ * import {UniqueIDProvider} from "@khanacademy/wonder-blocks-core";
56
+ *
57
+ * <UniqueIDProvider mockOnFirstRender={false} scope="field">
58
+ * {(ids) => (
59
+ * <>The id returned for "my-identifier": {ids.get("my-identifier")}</>
60
+ * )}
61
+ * </UniqueIDProvider>
62
+ * ```
63
+ */
64
+ export default class UniqueIDProvider extends React.Component<Props> {
65
+ _idFactory: IIdentifierFactory;
66
+ _performRender(firstRender: boolean): React.ReactNode;
67
+ render(): React.ReactNode;
68
+ }
69
+ export {};
@@ -0,0 +1,37 @@
1
+ import * as React from "react";
2
+ import type { TextViewSharedProps } from "../util/types";
3
+ type ValidViewTags = "div" | "article" | "aside" | "nav" | "section";
4
+ type Props = TextViewSharedProps & {
5
+ /**
6
+ * The HTML tag to render.
7
+ */
8
+ tag?: ValidViewTags;
9
+ };
10
+ /**
11
+ * View is a building block for constructing other components. `View` roughly
12
+ * maps to `div`. You can override which tag is used to render the component
13
+ * (for semantic purposes) by specifying the `tag` prop.
14
+ *
15
+ * These components can take styles (via the `style` prop) in a variety of
16
+ * manners:
17
+ *
18
+ * - An inline style object
19
+ * - An `aphrodite` StyleSheet style
20
+ * - An array combining the above
21
+ *
22
+ * `View` sets the following defaults:
23
+ *
24
+ * - `display: "flex"`
25
+ * - `flexDirection: "column"`
26
+ * - they each get their own stacking context.
27
+ *
28
+ * ### Usage
29
+ *
30
+ * ```jsx
31
+ * import {View} from "@khanacademy/wonder-blocks-core";
32
+ *
33
+ * <View>This is a View!</View>
34
+ * ```
35
+ */
36
+ declare const View: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLElement>>;
37
+ export default View;
@@ -0,0 +1,63 @@
1
+ import * as React from "react";
2
+ import { RenderState } from "./render-state-context";
3
+ /**
4
+ * We use render functions so that we don't do any work unless we need to.
5
+ * This avoids rendering but not mounting potentially complex component trees.
6
+ */
7
+ type Props = {
8
+ /**
9
+ * The content that is client-only. This is what is rendered when
10
+ * not server-side rendering, or (when server-side rendering) after
11
+ * the initial rehydration has finished.
12
+ */
13
+ children: () => React.ReactNode;
14
+ /**
15
+ * What to render during server-side rendering, or null not to
16
+ * render anything.
17
+ *
18
+ * NOTE: Make sure the placeholder will render the same for both
19
+ * client and server -- that is, it does the same thing for both
20
+ * the server-side renderer and the rehydration -- or it defeats
21
+ * the purpose of using the WithSSRPlaceholder component.
22
+ */
23
+ placeholder: (() => React.ReactNode) | null;
24
+ };
25
+ type State = {
26
+ mounted: boolean;
27
+ };
28
+ /**
29
+ * Defer or change rendering until the component did mount.
30
+ *
31
+ * The purpose of this component is to disable or modify server-side rendering
32
+ * of certain components. Disabling rendering on the server, by itself, would
33
+ * not be sufficient, since the initial render of the component must match what
34
+ * is rendered on the server. Therefore, this component also disables rendering
35
+ * the first time around on the client.
36
+ *
37
+ * If `WithSSRPlaceholder` components are nested within one another, the root
38
+ * `WithSSRPlaceholder` component will handle the initial render, but nested
39
+ * `WithSSRPlaceholder` components will delegate to the root one, meaning that
40
+ * we don't cascade delayed rendering down the component tree. This will also be
41
+ * the case across portal boundaries.
42
+ *
43
+ * ## Usage
44
+ *
45
+ * ```js
46
+ * import {WithSSRPlaceholder} from "@khanacademy/wonder-blocks-core";
47
+ *
48
+ * <WithSSRPlaceholder placeholder={() => <div>Renders on the server!</div>}>
49
+ * {() => (
50
+ * <div>This is rendered only by the client, for all renders after the rehydration render</div>
51
+ * )}
52
+ * </WithSSRPlaceholder>
53
+ * ```
54
+ */
55
+ export default class WithSSRPlaceholder extends React.Component<Props, State> {
56
+ state: State;
57
+ componentDidMount(): void;
58
+ _isTheRootComponent: boolean;
59
+ _renderAsRootComponent(): React.ReactNode;
60
+ _maybeRender(renderState: typeof RenderState[keyof typeof RenderState]): React.ReactNode;
61
+ render(): React.ReactNode;
62
+ }
63
+ export {};