Skip to content

Sandcastle using Stratakit #12731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: sandcastle-v2
Choose a base branch
from
Open

Sandcastle using Stratakit #12731

wants to merge 16 commits into from

Conversation

jjspace
Copy link
Contributor

@jjspace jjspace commented Jul 11, 2025

Description

The purpose of this PR was to do a full facelift to the new version of Sandcastle and embrace the Stratakit UI components. I also focused on solidifying the behavior of the various panels and parts of the app. It should now be very close to how we want it based on our latest designs.

What this PR does

  • Switch from itwin-ui to stratakit packages
    • Updated necessary CSS variables we were already using
  • Restructure the main App component to include a header and application/platform of left navigation
  • Added a console mirror with draggable height
  • Re-arranged the header buttons to be with the code editor
  • Restructured Gallery to be a panel covering the left side of the screen
  • Early localStorage based settings with the theme button
  • Add many icons from stratakit throughout for buttons

What this PR does NOT do

  • Gallery search - The inputs are there but do nothing
  • Modals, settings and the title/description metadata
  • Stratakit CSS in the bucket iframe
    • I re-define a few variables in the CSS for now, this will be changed in a separate PR

Issue number and link

Part of #12566

Testing plan

  • Run npm run dev from the Sandcastle package or npm run build-sandcastle and npm start from the root
  • Open the new sandcastle and play with it, this is a mostly visual change so check spacing, layout, interactions
    • I added a "viewerless" sandcastle for now to help when testing to not always have to load the viewer and WebGL context
  • Check the console is working as intended
    • Create a sandcastle that uses console.log, console.warn and console.error to make sure it displays them all correctly
    • Should auto-open if there are any warnings or errors
    • Should stay scrolled to the bottom as new messages come in
    • The multiple arguments issue will be fixed separately
    • Clicking to collapse and expand again should remember the height
  • Make sure loading the base route starts on the gallery. Make sure any route with a share string or id starts on the editor
  • Make sure the viewer area does not flash or double render when loading or picking new gallery items
  • Make sure the theme is remembered and stays the same after refreshing the page

Author checklist

  • I have submitted a Contributor License Agreement
  • I have added my name to CONTRIBUTORS.md
  • I have updated CHANGES.md with a short summary of my change
  • I have added or updated unit tests to ensure consistent code coverage
  • I have updated the inline documentation, and included code examples where relevant
  • I have performed a self-review of my code

@jjspace jjspace requested a review from ggetz July 11, 2025 21:16
Copy link

Thank you for the pull request, @jjspace!

✅ We can confirm we have a CLA on file for you.

@ggetz
Copy link
Contributor

ggetz commented Jul 22, 2025

Any of this can (and probably should) be addressed in a future PR, but here's UI feedback from playing around:

  • Bug: Console is not properly cleared between runs. To reproduce:

    1. Run the following example:
    import * as Cesium from "cesium";
    
    const viewer = new Cesium.Viewer("cesiumContainer");
    
    viewer.scene.postRender.addEventListener(() => {
      console.log("hello");
    });
    1. Open the console
    2. Comment out the console.log
    3. Hit run. About 3 logged "hello"s will show up.
  • UI suggestion: I agree with this user that the code window should probably not open by default when selecting a example from the gallery. It's a bit jarring when you are exploring the gallery.

  • Idea (low priority): A button in the console bar that fill pause the execution, like what's available in developer tools.

    image

Copy link
Contributor

@ggetz ggetz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jjspace! A few comments.

Comment on lines +167 to +174
"allotment": {
"use-resize-observer": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this all go in packages/sandcastle/package.json?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very annoyingly npm seems to ignore overrides in workspaces in monorepos. It didn't work until I added it here. I can try and dig into it more but I think this is simply a limitation we have to work around until the dependency itself gets updated (ZeeCoder/use-resize-observer#108) or allotment removes the dependency in favor of a "pure react" solution (johnwalley/allotment#833 (comment))


//const viewer = new Cesium.Viewer("cesiumContainer");

console.log("Sandcastle loaded");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the idea to keep this around, or clean it up before merging the PR?

I added a "viewerless" sandcastle for now to help when testing to not always have to load the viewer and WebGL context

If the former, I would probably suggest leaving it entirely blank.

@@ -16,25 +16,31 @@ body {
height: 100%;
overflow: hidden;

background-color: white;
background-color: var(--stratakit-color-bg-page-base);
background-image: var(--_rings), var(--_gradient);

/* TODO: these should pull from the stratakit directly somehow eventually */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this TODO now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I specifically left the pure CSS integration of stratakit into the bucket iframe for a separate PR. This will be addressed with that work.

toggleExpanded: () => void;
}) {
const logsRef = useRef<HTMLDivElement>(document.createElement("div"));
// TODO: determine if we need this lib or can implement ourselves. It's a little outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address or add an item to the running TODO list?

Comment on lines +61 to +67
const knownLabels = useMemo(() => {
const labels = new Set<string>();
for (const demo of demos) {
demo.labels?.forEach((label) => labels.add(label));
}
return [...labels].sort((a, b) => a.localeCompare(b));
}, [demos]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider aggregating these during the buildGallery script.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was removed in the search PR in favor of the list generated by pagefind. I'm gonna leave as is for this PR.

flex-shrink: 1;
/* Monaco needs a defined height for dynamic resizing to work */
--tabs-height: 1.5rem;
height: calc(100% - var(--tabs-height)) !important;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we avoid the !important somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc I added this because the monaco editor adds the height on the inline style tag which has "max priority" for styles. I'll take a peek at it again but I don't think so


background-image: var(--_rings), var(--_gradient);

/* TODO: these should pull from the stratakit directly somehow eventually */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove?

Comment on lines 14 to +16
define: {
__COMMIT_SHA__: JSON.stringify(undefined),
__CESIUM_VERSION__: JSON.stringify(`Cesium ${rootPackageJson.version}`),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment that may be easier to address later, but we may be able to remove some of the build complexity by grabbing this info during the buildGallery step.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants