From 72dcd7649d1e00c75f2ad2f6f1e9cc132ce48825 Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Thu, 15 Feb 2024 14:44:22 -0700 Subject: [PATCH] slots rock --- .../01.problem/toggle.tsx | 4 +- .../01.solution/toggle.tsx | 6 +- .../02.problem.validation/app.tsx | 2 +- .../02.problem.validation/toggle.tsx | 6 +- .../02.solution.validation/toggle.tsx | 6 +- .../04.slots/01.problem.context/README.mdx | 1 + .../app.tsx | 2 + .../index.css | 0 .../index.tsx | 0 .../04.slots/01.problem.context/slots.tsx | 18 ++++++ .../text-field.tsx | 4 ++ .../toggle.tsx | 6 +- exercises/04.slots/01.problem/slots.tsx | 7 --- .../04.slots/01.solution.context/README.mdx | 1 + .../app.tsx | 0 .../index.css | 0 .../index.tsx | 0 .../slots.tsx | 15 +---- .../text-field.tsx | 6 +- .../toggle.tsx | 6 +- .../04.slots/02.problem.generic/README.mdx | 1 + .../app.tsx | 3 + .../index.css | 0 .../index.tsx | 0 .../slots.tsx | 15 +---- .../text-field.tsx | 6 +- .../toggle.tsx | 16 ++++- exercises/04.slots/02.problem/README.mdx | 1 - .../04.slots/02.solution.generic/README.mdx | 1 + .../app.tsx | 0 .../index.css | 0 .../index.tsx | 0 .../04.slots/02.solution.generic/slots.tsx | 23 +++++++ .../text-field.tsx | 6 +- .../toggle.tsx | 11 ++-- exercises/04.slots/02.solution/README.mdx | 1 - exercises/04.slots/02.solution/slots.tsx | 44 ------------- .../README.mdx | 0 .../{03.problem => 03.problem.prop}/app.tsx | 2 + .../{03.problem => 03.problem.prop}/index.css | 0 .../{03.problem => 03.problem.prop}/index.tsx | 0 exercises/04.slots/03.problem.prop/slots.tsx | 51 +++++++++++++++ .../text-field.tsx | 6 +- .../toggle.tsx | 20 ++++-- exercises/04.slots/03.problem/README.mdx | 1 - exercises/04.slots/03.problem/slots.tsx | 62 ------------------- .../README.mdx | 0 .../{03.solution => 03.solution.prop}/app.tsx | 0 .../index.css | 0 .../index.tsx | 0 .../slots.tsx | 25 +++----- .../04.slots/03.solution.prop/text-field.tsx | 22 +++++++ .../toggle.tsx | 8 +-- exercises/04.slots/03.solution/README.mdx | 1 - exercises/04.slots/03.solution/text-field.tsx | 22 ------- .../06.state-reducer/01.problem/toggle.tsx | 2 +- .../06.state-reducer/01.solution/toggle.tsx | 2 +- .../02.problem.default/toggle.tsx | 2 +- .../02.solution.default/toggle.tsx | 2 +- shared/switch.tsx | 2 +- 60 files changed, 215 insertions(+), 233 deletions(-) create mode 100644 exercises/04.slots/01.problem.context/README.mdx rename exercises/04.slots/{01.solution => 01.problem.context}/app.tsx (79%) rename exercises/04.slots/{01.problem => 01.problem.context}/index.css (100%) rename exercises/04.slots/{01.problem => 01.problem.context}/index.tsx (100%) create mode 100644 exercises/04.slots/01.problem.context/slots.tsx rename exercises/04.slots/{01.problem => 01.problem.context}/text-field.tsx (54%) rename exercises/04.slots/{02.problem => 01.problem.context}/toggle.tsx (84%) delete mode 100644 exercises/04.slots/01.problem/slots.tsx create mode 100644 exercises/04.slots/01.solution.context/README.mdx rename exercises/04.slots/{01.problem => 01.solution.context}/app.tsx (100%) rename exercises/04.slots/{01.solution => 01.solution.context}/index.css (100%) rename exercises/04.slots/{01.solution => 01.solution.context}/index.tsx (100%) rename exercises/04.slots/{02.problem => 01.solution.context}/slots.tsx (61%) rename exercises/04.slots/{01.solution => 01.solution.context}/text-field.tsx (66%) rename exercises/04.slots/{01.solution => 01.solution.context}/toggle.tsx (84%) create mode 100644 exercises/04.slots/02.problem.generic/README.mdx rename exercises/04.slots/{02.problem => 02.problem.generic}/app.tsx (80%) rename exercises/04.slots/{02.problem => 02.problem.generic}/index.css (100%) rename exercises/04.slots/{02.problem => 02.problem.generic}/index.tsx (100%) rename exercises/04.slots/{01.solution => 02.problem.generic}/slots.tsx (61%) rename exercises/04.slots/{03.problem => 02.problem.generic}/text-field.tsx (66%) rename exercises/04.slots/{01.problem => 02.problem.generic}/toggle.tsx (61%) delete mode 100644 exercises/04.slots/02.problem/README.mdx create mode 100644 exercises/04.slots/02.solution.generic/README.mdx rename exercises/04.slots/{02.solution => 02.solution.generic}/app.tsx (100%) rename exercises/04.slots/{02.solution => 02.solution.generic}/index.css (100%) rename exercises/04.slots/{02.solution => 02.solution.generic}/index.tsx (100%) create mode 100644 exercises/04.slots/02.solution.generic/slots.tsx rename exercises/04.slots/{02.problem => 02.solution.generic}/text-field.tsx (66%) rename exercises/04.slots/{03.problem => 02.solution.generic}/toggle.tsx (88%) delete mode 100644 exercises/04.slots/02.solution/README.mdx delete mode 100644 exercises/04.slots/02.solution/slots.tsx rename exercises/04.slots/{01.problem => 03.problem.prop}/README.mdx (100%) rename exercises/04.slots/{03.problem => 03.problem.prop}/app.tsx (77%) rename exercises/04.slots/{03.problem => 03.problem.prop}/index.css (100%) rename exercises/04.slots/{03.problem => 03.problem.prop}/index.tsx (100%) create mode 100644 exercises/04.slots/03.problem.prop/slots.tsx rename exercises/04.slots/{02.solution => 03.problem.prop}/text-field.tsx (66%) rename exercises/04.slots/{02.solution => 03.problem.prop}/toggle.tsx (75%) delete mode 100644 exercises/04.slots/03.problem/README.mdx delete mode 100644 exercises/04.slots/03.problem/slots.tsx rename exercises/04.slots/{01.solution => 03.solution.prop}/README.mdx (100%) rename exercises/04.slots/{03.solution => 03.solution.prop}/app.tsx (100%) rename exercises/04.slots/{03.solution => 03.solution.prop}/index.css (100%) rename exercises/04.slots/{03.solution => 03.solution.prop}/index.tsx (100%) rename exercises/04.slots/{03.solution => 03.solution.prop}/slots.tsx (70%) create mode 100644 exercises/04.slots/03.solution.prop/text-field.tsx rename exercises/04.slots/{03.solution => 03.solution.prop}/toggle.tsx (85%) delete mode 100644 exercises/04.slots/03.solution/README.mdx delete mode 100644 exercises/04.slots/03.solution/text-field.tsx diff --git a/exercises/03.compound-components/01.problem/toggle.tsx b/exercises/03.compound-components/01.problem/toggle.tsx index c9b50a4f..3ce5a32a 100644 --- a/exercises/03.compound-components/01.problem/toggle.tsx +++ b/exercises/03.compound-components/01.problem/toggle.tsx @@ -31,9 +31,7 @@ export function ToggleOff({ children }: { children: React.ReactNode }) { return <>{on ? null : children} } -export function ToggleButton( - props: Omit, 'on' | 'onClick'>, -) { +export function ToggleButton(props: React.ComponentProps) { // 🐨 get `on` and `toggle` from the ToggleContext with `use` const on = false const toggle = () => {} diff --git a/exercises/03.compound-components/01.solution/toggle.tsx b/exercises/03.compound-components/01.solution/toggle.tsx index 95189164..c0cd9f87 100644 --- a/exercises/03.compound-components/01.solution/toggle.tsx +++ b/exercises/03.compound-components/01.solution/toggle.tsx @@ -1,8 +1,8 @@ -import { use, useState } from 'react' +import { createContext, use, useState } from 'react' import { Switch } from '#shared/switch.tsx' type ToggleValue = { on: boolean; toggle: () => void } -const ToggleContext = React.createContext(undefined) +const ToggleContext = createContext(undefined) ToggleContext.displayName = 'ToggleContext' export function Toggle({ children }: { children: React.ReactNode }) { @@ -28,7 +28,7 @@ export function ToggleOff({ children }: { children: React.ReactNode }) { export function ToggleButton({ ...props -}: Omit, 'on' | 'onClick'>) { +}: Omit, 'on'>) { const { on, toggle } = use(ToggleContext)! return } diff --git a/exercises/03.compound-components/02.problem.validation/app.tsx b/exercises/03.compound-components/02.problem.validation/app.tsx index 0544e966..34deeebe 100644 --- a/exercises/03.compound-components/02.problem.validation/app.tsx +++ b/exercises/03.compound-components/02.problem.validation/app.tsx @@ -1,4 +1,4 @@ -import { Toggle, ToggleOn, ToggleOff, ToggleButton } from './toggle.tsx' +import { Toggle, ToggleButton, ToggleOff, ToggleOn } from './toggle.tsx' export function App() { return ( diff --git a/exercises/03.compound-components/02.problem.validation/toggle.tsx b/exercises/03.compound-components/02.problem.validation/toggle.tsx index 95189164..c0cd9f87 100644 --- a/exercises/03.compound-components/02.problem.validation/toggle.tsx +++ b/exercises/03.compound-components/02.problem.validation/toggle.tsx @@ -1,8 +1,8 @@ -import { use, useState } from 'react' +import { createContext, use, useState } from 'react' import { Switch } from '#shared/switch.tsx' type ToggleValue = { on: boolean; toggle: () => void } -const ToggleContext = React.createContext(undefined) +const ToggleContext = createContext(undefined) ToggleContext.displayName = 'ToggleContext' export function Toggle({ children }: { children: React.ReactNode }) { @@ -28,7 +28,7 @@ export function ToggleOff({ children }: { children: React.ReactNode }) { export function ToggleButton({ ...props -}: Omit, 'on' | 'onClick'>) { +}: Omit, 'on'>) { const { on, toggle } = use(ToggleContext)! return } diff --git a/exercises/03.compound-components/02.solution.validation/toggle.tsx b/exercises/03.compound-components/02.solution.validation/toggle.tsx index e4920d3c..2d337769 100644 --- a/exercises/03.compound-components/02.solution.validation/toggle.tsx +++ b/exercises/03.compound-components/02.solution.validation/toggle.tsx @@ -1,8 +1,8 @@ -import { use, useState } from 'react' +import { createContext, use, useState } from 'react' import { Switch } from '#shared/switch.tsx' type ToggleValue = { on: boolean; toggle: () => void } -const ToggleContext = React.createContext(undefined) +const ToggleContext = createContext(undefined) ToggleContext.displayName = 'ToggleContext' export function Toggle({ children }: { children: React.ReactNode }) { @@ -38,7 +38,7 @@ export function ToggleOff({ children }: { children: React.ReactNode }) { export function ToggleButton({ ...props -}: Omit, 'on' | 'onClick'>) { +}: Omit, 'on'>) { const { on, toggle } = useToggle() return } diff --git a/exercises/04.slots/01.problem.context/README.mdx b/exercises/04.slots/01.problem.context/README.mdx new file mode 100644 index 00000000..892c37f1 --- /dev/null +++ b/exercises/04.slots/01.problem.context/README.mdx @@ -0,0 +1 @@ +# Slot Context diff --git a/exercises/04.slots/01.solution/app.tsx b/exercises/04.slots/01.problem.context/app.tsx similarity index 79% rename from exercises/04.slots/01.solution/app.tsx rename to exercises/04.slots/01.problem.context/app.tsx index a7f61ea8..ca6334d4 100644 --- a/exercises/04.slots/01.solution/app.tsx +++ b/exercises/04.slots/01.problem.context/app.tsx @@ -17,7 +17,9 @@ export function App() {
+ {/* 🦉 feel free to test the id customization by passing an id here */} + {/* 🦉 feel free to test the prop merging by passing props here */} diff --git a/exercises/04.slots/01.problem/index.css b/exercises/04.slots/01.problem.context/index.css similarity index 100% rename from exercises/04.slots/01.problem/index.css rename to exercises/04.slots/01.problem.context/index.css diff --git a/exercises/04.slots/01.problem/index.tsx b/exercises/04.slots/01.problem.context/index.tsx similarity index 100% rename from exercises/04.slots/01.problem/index.tsx rename to exercises/04.slots/01.problem.context/index.tsx diff --git a/exercises/04.slots/01.problem.context/slots.tsx b/exercises/04.slots/01.problem.context/slots.tsx new file mode 100644 index 00000000..20ea7c3c --- /dev/null +++ b/exercises/04.slots/01.problem.context/slots.tsx @@ -0,0 +1,18 @@ +// 🦺 create a Slots type that's just an object of objects +// 🐨 create and export a SlotContext with that type and default it to an empty object + +// 🐨 create a useSlotProps hook which: +// 1. accepts props (any type) and slot (string) +// 2. gets the slots from the SlotContext +// 3. gets the props from the slot by its name +// 4. returns the merged props with the slot and given props + +export function Label(props: React.ComponentProps<'label'>) { + // 🐨 get the props from useSlotProps for a slot called "label" and apply those to the label + return