Skip to content

Survey Customization Recipe

Patterns for customizing Sibilance survey behavior and appearance.

Overview

This recipe covers ways to customize surveys, including styling, behavior, and integration patterns.

Styling

Custom Button Styles

tsx
import { FloatingMicButton } from '@sibilance.is/client/react';

function CustomButton() {
  const { voiceState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here'
  });

  return (
    <FloatingMicButton
      isConnected={voiceState.isConnected}
      onClick={toggleSession}
      style={{
        '--sibilance-primary-color': '#007bff',
        '--sibilance-background': '#ffffff',
        '--sibilance-border-radius': '50%',
        '--sibilance-shadow': '0 4px 12px rgba(0, 0, 0, 0.15)'
      } as React.CSSProperties}
    />
  );
}

Custom CSS

css
/* Override default styles */
.sibilance-microphone {
  --sibilance-primary-color: #007bff;
  --sibilance-background: #ffffff;
  --sibilance-border-radius: 50%;
}

.sibilance-microphone::part(button) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  box-shadow: 0 8px 16px rgba(102, 126, 234, 0.4);
}

.sibilance-microphone::part(button):hover {
  transform: scale(1.1);
  transition: transform 0.2s;
}

Behavior Customization

Auto-Start Survey

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here',
  autoStart: true  // Start automatically
}, {
  onComplete: (yaml) => {
    console.log('Survey completed!', yaml);
  }
});

Custom Instructions

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here',
  customInstructions: `
    Please be friendly and conversational.
    If the user seems confused, offer to clarify.
    Keep responses brief and to the point.
  `
});

Voice Configuration

typescript
const client = new SibilanceClient({
  surveyKey: 'sibilance_your_key_here',
  voiceConfig: {
    provider: 'gemini',  // or 'openai', 'vowel-prime'
    model: 'gemini-2.0-flash-exp',
    voiceId: 'alloy',  // OpenAI voice ID
    speakingRate: 1.0  // 0.5 to 2.0
  }
});

Conditional Logic

Show Survey Based on Conditions

tsx
function ConditionalSurvey() {
  const [shouldShow, setShouldShow] = useState(false);
  const { voiceState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here',
    autoStart: false
  });

  useEffect(() => {
    // Show survey after 5 seconds
    const timer = setTimeout(() => {
      setShouldShow(true);
    }, 5000);
    
    return () => clearTimeout(timer);
  }, []);

  if (!shouldShow) return null;

  return (
    <FloatingMicButton
      isConnected={voiceState.isConnected}
      onClick={toggleSession}
    />
  );
}

Survey Based on User Action

tsx
function ActionTriggeredSurvey() {
  const [showSurvey, setShowSurvey] = useState(false);
  const { voiceState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here',
    autoStart: false
  });

  return (
    <div>
      <button onClick={() => setShowSurvey(true)}>
        Start Survey
      </button>
      
      {showSurvey && (
        <FloatingMicButton
          isConnected={voiceState.isConnected}
          onClick={toggleSession}
        />
      )}
    </div>
  );
}

Integration Patterns

tsx
function ModalSurvey() {
  const [isOpen, setIsOpen] = useState(false);
  const { voiceState, surveyState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here'
  }, {
    onComplete: (yaml) => {
      console.log('Survey completed!', yaml);
      setIsOpen(false);
    }
  });

  return (
    <>
      <button onClick={() => setIsOpen(true)}>
        Open Survey
      </button>
      
      {isOpen && (
        <div className="modal">
          <div className="modal-content">
            <button onClick={() => setIsOpen(false)}>Close</button>
            
            {surveyState.isActive && (
              <div className="survey-status">
                Survey in progress...
              </div>
            )}
            
            <FloatingMicButton
              isConnected={voiceState.isConnected}
              onClick={toggleSession}
            />
          </div>
        </div>
      )}
    </>
  );
}

Inline Survey Widget

tsx
function InlineSurvey() {
  const { voiceState, surveyState, toggleSession } = useSibilance({
    surveyKey: 'sibilance_your_key_here'
  });

  return (
    <div className="inline-survey">
      <h3>Voice Survey</h3>
      
      <button onClick={toggleSession}>
        {voiceState.isConnected ? 'Stop Survey' : 'Start Survey'}
      </button>
      
      {surveyState.isActive && (
        <div className="progress">
          <p>Current step: {surveyState.currentStepId}</p>
          <p>Collected: {surveyState.collectedInfo.length} items</p>
        </div>
      )}
    </div>
  );
}