Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ The project uses a [GitHub Project board](https://github.com/users/jbourdin/proj
5. **Move the issue** to "Ready for Release" when the user confirms the feature works
6. **Move the issue** to "Done" only when the release containing it is published

When creating new features or backlog items, create a GitHub issue with the feature ID, assign it to the correct milestone, and add it to the project board. **Always set the status to "Backlog"** when adding an issue to the board — items must never be left without a kanban status.
When creating new features or backlog items, create a GitHub issue with the feature ID and add it to the project board. **Always set the status to "Backlog"** when adding an issue to the board — items must never be left without a kanban status. Do **not** assign milestones — the phase milestones in the repo are not used as a planning structure.

**Board ordering:** items within each column are manually sorted by **milestone** (Phase A first, then B, C, … J, then no milestone) and then by **priority** (high → medium → low) within a milestone. When adding or moving an issue, place it at the correct position using the `updateProjectV2ItemPosition` GraphQL mutation (`afterId: null` for first position, or `afterId: "<previous-item-id>"` to insert after a specific item).
**Board ordering:** items within each column are sorted manually by user direction. When adding or moving an issue, place it at the correct position using the `updateProjectV2ItemPosition` GraphQL mutation (`afterId: null` for first position, or `afterId: "<previous-item-id>"` to insert after a specific item).

## Make Commands

Expand Down
14 changes: 7 additions & 7 deletions assets/archetype-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import PlaystyleTagSelect from './components/PlaystyleTagSelect';
import PokemonSpriteSelect from './components/PokemonSpriteSelect';
import MarkdownEditor from './components/MarkdownEditor';
Expand Down Expand Up @@ -39,12 +39,12 @@ if (spriteRoot) {
const hiddenInputName = spriteRoot.dataset.hiddenInputName ?? 'archetype_form[pokemonSlugs]';

createRoot(spriteRoot).render(
<MantineProvider>
<AppMantineProvider>
<PokemonSpriteSelect
initialValues={initialSlugs}
hiddenInputName={hiddenInputName}
/>
</MantineProvider>,
</AppMantineProvider>,
);
}

Expand Down Expand Up @@ -74,14 +74,14 @@ if (playstyleRoot) {
const placeholder = playstyleRoot.dataset.placeholder ?? undefined;

createRoot(playstyleRoot).render(
<MantineProvider>
<AppMantineProvider>
<PlaystyleTagSelect
existingTags={existingTags}
initialValues={initialValues}
hiddenInputName="archetype_form[playstyleTags]"
placeholder={placeholder}
/>
</MantineProvider>,
</AppMantineProvider>,
);
}

Expand All @@ -98,12 +98,12 @@ editorRoots.forEach((root) => {
}

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<MarkdownEditor
textareaSelector={`#${textareaId}`}
initialContent={textarea.value}
placeholder={textarea.placeholder}
/>
</MantineProvider>,
</AppMantineProvider>,
);
});
6 changes: 3 additions & 3 deletions assets/archetype-variants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import '@mantine/core/styles.css';
import ArchetypeVariantSelector from './components/ArchetypeVariantSelector';

Expand Down Expand Up @@ -47,8 +47,8 @@ if (root) {
};

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<ArchetypeVariantSelector variants={variants} labels={labels} archetypeSlug={archetypeSlug} canCopyTag={canCopyTag} />
</MantineProvider>,
</AppMantineProvider>,
);
}
6 changes: 3 additions & 3 deletions assets/banned-card-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import MarkdownEditor from './components/MarkdownEditor';

import '@mantine/core/styles.css';
Expand All @@ -33,12 +33,12 @@ editorRoots.forEach((root) => {
}

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<MarkdownEditor
textareaSelector={`#${textareaId}`}
initialContent={textarea.value}
placeholder={textarea.placeholder}
/>
</MantineProvider>,
</AppMantineProvider>,
);
});
14 changes: 7 additions & 7 deletions assets/catalog-filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import ArchetypeFilterSelect from './components/ArchetypeFilterSelect';
import AsyncAutocomplete from './components/AsyncAutocomplete';

Expand All @@ -34,15 +34,15 @@ document.querySelectorAll<HTMLElement>('[data-catalog-archetype]').forEach((root
const initialLabel = root.dataset.initialLabel ?? '';

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<ArchetypeFilterSelect
catalogUrl={catalogUrl}
hiddenInputName={hiddenInput}
placeholder={placeholder}
initialValue={initialValue}
initialLabel={initialLabel}
/>
</MantineProvider>,
</AppMantineProvider>,
);
});

Expand All @@ -54,7 +54,7 @@ document.querySelectorAll<HTMLElement>('[data-catalog-event]').forEach((root) =>
const initialId = root.dataset.initialId ?? '';

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<AsyncAutocomplete
searchUrl={searchUrl}
hiddenInputName={hiddenInput}
Expand All @@ -67,7 +67,7 @@ document.querySelectorAll<HTMLElement>('[data-catalog-event]').forEach((root) =>
secondary: `${item.date as string} · ${item.location as string}`,
})}
/>
</MantineProvider>,
</AppMantineProvider>,
);
});

Expand All @@ -79,7 +79,7 @@ document.querySelectorAll<HTMLElement>('[data-catalog-owner]').forEach((root) =>
const initialId = root.dataset.initialId ?? '';

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<AsyncAutocomplete
searchUrl={searchUrl}
hiddenInputName={hiddenInput}
Expand All @@ -91,6 +91,6 @@ document.querySelectorAll<HTMLElement>('[data-catalog-owner]').forEach((root) =>
label: item.screenName as string,
})}
/>
</MantineProvider>,
</AppMantineProvider>,
);
});
27 changes: 27 additions & 0 deletions assets/components/AppMantineProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* This file is part of the Expanded Decks project.
*
* (c) Expanded Decks contributors
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import React from 'react';
import { MantineProvider } from '@mantine/core';

/**
* Shared Mantine provider for all React islands in the app. Configures
* Mantine to follow the operating-system color scheme (`auto`) so it stays
* in sync with the `data-bs-theme` attribute set on `<html>` by the inline
* bridge script in base.html.twig.
*
* @see docs/features.md F20.1 — Dark theme following OS preference
*/
export default function AppMantineProvider({ children }: { children: React.ReactNode }) {
return (
<MantineProvider defaultColorScheme="auto">
{children}
</MantineProvider>
);
}
6 changes: 3 additions & 3 deletions assets/deck-card-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import { DeckCardList, type DeckCardListProps } from './components/DeckCardList';

import '@mantine/core/styles.css';
Expand Down Expand Up @@ -55,7 +55,7 @@ if (root) {
};

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<DeckCardList
originalCards={originalCards}
minifiedCards={minifiedCards}
Expand All @@ -67,6 +67,6 @@ if (root) {
deckName={root.dataset.deckName ?? ''}
labels={labels}
/>
</MantineProvider>,
</AppMantineProvider>,
);
}
14 changes: 7 additions & 7 deletions assets/deck-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import ArchetypeSelect from './components/ArchetypeSelect';
import LanguageSelect from './components/LanguageSelect';
import PokemonSpriteSelect from './components/PokemonSpriteSelect';
Expand All @@ -32,15 +32,15 @@ if (archetypeRoot) {
const initialName = archetypeRoot.dataset.archetypeName ?? undefined;

createRoot(archetypeRoot).render(
<MantineProvider>
<AppMantineProvider>
<ArchetypeSelect
searchUrl={searchUrl}
createUrl={createUrl}
initialId={initialId}
initialName={initialName}
hiddenInputName="deck_form[archetype]"
/>
</MantineProvider>,
</AppMantineProvider>,
);
}

Expand All @@ -57,12 +57,12 @@ if (languageRoot) {
}

createRoot(languageRoot).render(
<MantineProvider>
<AppMantineProvider>
<LanguageSelect
initialLanguages={initialLanguages}
hiddenInputName="deck_form[languages]"
/>
</MantineProvider>,
</AppMantineProvider>,
);
}

Expand All @@ -79,11 +79,11 @@ if (spriteRoot) {
}

createRoot(spriteRoot).render(
<MantineProvider>
<AppMantineProvider>
<PokemonSpriteSelect
initialValues={initialSlugs}
hiddenInputName="deck_form[pokemonSlugs]"
/>
</MantineProvider>,
</AppMantineProvider>,
);
}
6 changes: 3 additions & 3 deletions assets/deck-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/

import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import '@mantine/core/styles.css';
import DeckFoundModal from './components/DeckFoundModal';

Expand All @@ -26,7 +26,7 @@ if (root) {
const labels = JSON.parse(root.dataset.labels ?? '{}');

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<DeckFoundModal
apiUrl={apiUrl}
csrfToken={csrfToken}
Expand All @@ -35,6 +35,6 @@ if (root) {
sitekey={sitekey}
labels={labels}
/>
</MantineProvider>,
</AppMantineProvider>,
);
}
6 changes: 3 additions & 3 deletions assets/deck-version-compare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import DeckVersionCompare from './components/DeckVersionCompare';

import '@mantine/core/styles.css';
Expand Down Expand Up @@ -45,8 +45,8 @@ document.querySelectorAll<HTMLElement>('[data-version-compare]').forEach((root)
};

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<DeckVersionCompare shortTag={shortTag} compareUrl={compareUrl} versions={versions} labels={labels} />
</MantineProvider>,
</AppMantineProvider>,
);
});
6 changes: 3 additions & 3 deletions assets/event-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import React from 'react';
import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import EventTagSelect from './components/EventTagSelect';

import '@mantine/core/styles.css';
Expand Down Expand Up @@ -46,13 +46,13 @@ if (tagRoot) {
const placeholder = tagRoot.dataset.placeholder ?? '';

createRoot(tagRoot).render(
<MantineProvider>
<AppMantineProvider>
<EventTagSelect
existingTags={existingTags}
initialValues={initialValues}
hiddenInputName={hiddenInputName}
placeholder={placeholder}
/>
</MantineProvider>,
</AppMantineProvider>,
);
}
6 changes: 3 additions & 3 deletions assets/homepage-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
*/

import { createRoot } from 'react-dom/client';
import { MantineProvider } from '@mantine/core';
import AppMantineProvider from './components/AppMantineProvider';
import HomepageEditor from './components/HomepageEditor';

import '@mantine/core/styles.css';
Expand Down Expand Up @@ -61,7 +61,7 @@ if (root) {
} catch { /* use default */ }

createRoot(root).render(
<MantineProvider>
<AppMantineProvider>
<HomepageEditor
saveUrl={saveUrl}
previewUrl={previewUrl}
Expand All @@ -73,6 +73,6 @@ if (root) {
blockTypes={blockTypes}
labels={labels}
/>
</MantineProvider>,
</AppMantineProvider>,
);
}
Loading
Loading