Skip to content
Open
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
48 changes: 48 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

idyll-embed is a JavaScript library that bundles the Idyll runtime for embedding interactive Idyll documents directly into HTML pages. It provides a single minified script that can be included via a script tag, exposing global `Idyll` and `IdyllComponents` objects.

## Commands

### Build
```bash
npm run build
```
Builds the project using webpack, creating `dist/idyll-embed.min.js`.

### Development
```bash
npm install
```
Install all dependencies before development.

## Architecture

The project has a simple architecture centered around bundling Idyll for browser use:

1. **Entry Point**: `index.js` imports Idyll, React, and ReactDOM, then creates the global API:
- `Idyll.render(markup, container, options)` - Renders Idyll markup
- `Idyll.registerComponent(name, component)` - Registers custom components
- `window.IdyllComponents` - Exposes all built-in Idyll components

2. **Build Process**: Webpack bundles everything into a single minified file, using Babel to transpile JSX and modern JavaScript.

3. **Usage Pattern**: Users include the script, create a container div, and call `Idyll.render()` with their markup.

## Key Dependencies

- **idyll**: 5.x (core framework)
- **React/ReactDOM**: Bundled as Idyll's rendering engine
- **Webpack 4**: Build tooling
- **Babel**: JavaScript transpilation

## Important Notes

- The project was recently modernized to Idyll 5.x
- No test framework is currently set up
- The dist folder contains the built output
- Legacy build tools (browserify, uglify-js) are present in package.json but webpack is the primary build system
67 changes: 2 additions & 65 deletions dist/idyll-embed.min.js

Large diffs are not rendered by default.

84 changes: 84 additions & 0 deletions dist/idyll-embed.min.js.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <http://feross.org>
* @license MIT
*/

/*!
* is-extendable <https://github.com/jonschlinkert/is-extendable>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/

/*!
* strip-bom-string <https://github.com/jonschlinkert/strip-bom-string>
*
* Copyright (c) 2015, 2017, Jon Schlinkert.
* Released under the MIT License.
*/

/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

/**
* @link https://github.com/gajus/sister for the canonical source repository
* @license https://github.com/gajus/sister/blob/master/LICENSE BSD 3-Clause
*/

/** @license React v0.19.1
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.14.0
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.14.0
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license URI.js v4.2.1 (c) 2011 Gary Court. License: http://github.com/garycourt/uri-js */
1 change: 1 addition & 0 deletions dist/idyll-embed.min.js.map

Large diffs are not rendered by default.

88 changes: 86 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,93 @@
var idyllMarkup = `
[Header title:"Hello World" author:"Matthew Conlen" fullWidth:true /]

Normal paragraph text.
[var name:'currentStep' value:1 /]
[var name:'fullData' value:\`[
{complexity: 0, understanding: 30},
{complexity: 1, understanding: 40},
{complexity: 2, understanding: 50},
{complexity: 3, understanding: 65},
{complexity: 4, understanding: 75},
{complexity: 5, understanding: 82},
{complexity: 6, understanding: 86},
{complexity: 7, understanding: 88},
{complexity: 8, understanding: 87},
{complexity: 9, understanding: 83},
{complexity: 10, understanding: 75},
{complexity: 11, understanding: 65},
{complexity: 12, understanding: 50},
{complexity: 13, understanding: 40},
{complexity: 14, understanding: 35},
{complexity: 15, understanding: 40},
{complexity: 16, understanding: 50},
{complexity: 17, understanding: 65},
{complexity: 18, understanding: 80},
{complexity: 19, understanding: 90},
{complexity: 20, understanding: 95},
{complexity: 21, understanding: 97},
{complexity: 22, understanding: 98},
{complexity: 23, understanding: 99},
{complexity: 24, understanding: 99}
]\` /]

## Subheader
[derived name:'visibleData' value:\`currentStep === 1 ? fullData.slice(0, 8) : currentStep === 2 ? fullData.slice(0, 14) : fullData\` /]

[div className:'chart-container']
#### The Shape of Understanding

[Chart
type:'line'
data:visibleData
x:'complexity'
y:'understanding'
range:\`[0, 100]\`
domain:\`[0, 25]\`
/]
[div className:'button-container' style:\`{textAlign: "center"}\`]
[em] Complexity [/em]
[Button
style:\`{
display: "inline",
background: currentStep <= 1 ? 'gray' : 'white',
cursor: currentStep <= 1 ? "not-allowed" : "pointer",
}\`
disabled:\`currentStep <= 1\`
onClick:\`currentStep = Math.max(1, currentStep - 1)\`
]
-
[/Button]
[Button
style:\`{
display: "inline",
background: currentStep >= 3 ? 'gray' : 'white',
cursor: currentStep >= 3 ? "not-allowed" : "pointer",
}\`
disabled:\`currentStep >= 3\`
onClick:\`currentStep = Math.min(3, currentStep + 1)\`
]
+
[/Button]
[/div]
[div className:'narrative-text']
[Conditional if:\`currentStep === 1\`]
We used to think it was simple: add complexity, gain understanding.
Until you hit the peak...
[/Conditional]
[Conditional if:\`currentStep === 2\`]
Then confusion sets in.
More parameters, *less* understanding.

The model memorizes but doesn't comprehend.
[/Conditional]
[Conditional if:\`currentStep === 3\`]
But keep going...
Something beautiful emerges.
A deeper kind of understanding.

**The double descent.**
[/Conditional]
[/div]
[/div]

`;

Expand Down
45 changes: 41 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,35 @@ import * as IdyllComponents from 'idyll-components';
* MyComponent: MyComponent
* })
*/
let components = Object.assign({}, IdyllComponents, {
// put more components here
});

// Function to ensure components are properly wrapped
function wrapComponent(Component) {
// Check if it's already a valid React component
if (
typeof Component === 'function' ||
(typeof Component === 'object' && Component && Component.$$typeof)
) {
return Component;
}

// If it's a class that needs wrapping, create a functional wrapper
if (Component && Component.prototype && Component.prototype.isReactComponent) {
return Component;
}

// Return as-is for other cases
return Component;
}

// Wrap all components to ensure they work properly
const wrappedComponents = {};
Object.keys(IdyllComponents).forEach(key => {
wrappedComponents[key] = wrapComponent(IdyllComponents[key]);
});

let components = Object.assign({}, wrappedComponents, {
// put more components here
});

const Idyll = {
render: function(markup, container, options = {}) {
Expand All @@ -36,4 +62,15 @@ const Idyll = {
}
}

window.Idyll = Idyll;
window.Idyll = Idyll;
window.IdyllComponents = wrappedComponents;

// Expose all component class names (starting with uppercase) as globals
// Skip native JavaScript constructors to avoid conflicts
const nativeConstructors = ['Boolean', 'Number', 'String', 'Array', 'Object', 'Function', 'Date', 'RegExp', 'Error'];
Object.keys(wrappedComponents).forEach(key => {
if (key[0] === key[0].toUpperCase() && !nativeConstructors.includes(key)) {
window[key] = wrappedComponents[key];
}
});

Loading